多线程的三大特性:
1.原子性。保证线程安全问题,保证数据的原子性和完整性。
2.可见性。当多个多线程访问同一个变量的时候,一个线程的值改变话其他的线程可以立即看到修改后的值。
3.有序性。程序的执行顺序按照代码的执行顺序。
Java内存模型:简称JMM
Java内存模型表明一个线程对共享变量进行写入时,能对另外一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象的关系:线程之间的共享变量存储在主内存中,每一个线程都一个私有的本地内存,本地内存中存储了该线程按照读或者写共享变量的副本。本地内存是JMM的一个抽象概念,并不是真实存在的,它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器的优化。
Volatile:
Volatile 关键字表示变量在多个线程之间是可见。
下面的代码中使用volatile关键字可以保证线程的可见性。
package com.itmayiedu.day02;
import javax.swing.*;
/** * Volatile 关键字 保证线程之间是可见的 但不保证原子性。 */
public class ThreadTrainDemo06 extends Thread {
private volatile boolean flag = true;//使用volatile可以保证线程的可见性,当主线程修改主内存的数据是 子线程的数据也会立即修改。
@Override
public void run() {
System.out.println("===================>>>>>>> 子线程开始执行。。。。。");
while (flag){
// System.out.println("我还在执行的。。。。。。");
}
System.out.println("=====================>>>>>>子线程执行完毕");
}
public void setFlag(Boolean flag){
this.flag =flag;
}
public boolean isFlag() {
return flag;
}
public static void main(String[] args) throws Exception {
ThreadTrainDemo06 threadTrainDemo06 = new ThreadTrainDemo06();
threadTrainDemo06.start();
Thread.sleep(1000);//线程停止三秒。
threadTrainDemo06.setFlag(false); //主线程修改全局变量是false,如果没有使用volatile 主内存的不会同步到子线程的本地内存中。
System.out.println("Flag已经修改成false");
Thread.sleep(1000);
System.out.println(threadTrainDemo06.isFlag()+"");
}
}
注意:volatile可以保证线程的但是不保证原子性。
在jdk1.5中加入了atomic包可以解决线程的安全性问题和原子性。
package com.itmayiedu.day02;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadTrainDemo07 extends Thread {
//是个线程同时共享count;static关键字修饰的会被所有的线程共享。
// private volatile static int count = 0 ;
private static AtomicInteger count = new AtomicInteger(0);//保证数据原子性问题。
@Override
public void run() {
for (int i = 0; i <1000 ; i++) {
// count++;
count.incrementAndGet(); //在这里标示自增
}
System.out.println(Thread.currentThread().getName()+": "+count.get());//获取count的值。
}
public static void main(String[] args) {
ThreadTrainDemo07 [] threadTrainDemo07s =new ThreadTrainDemo07[10];
for (int i = 0; i <10 ; i++) {
threadTrainDemo07s[i] = new ThreadTrainDemo07();
}
/*for (ThreadTrainDemo07 threadTrainDemo07:threadTrainDemo07s) { threadTrainDemo07.start(); }*/
for (int i = 0; i <10 ; i++) {
threadTrainDemo07s[i].start();
}
}
}