volatile关键字主要作用与使用
1.作用
实现线程本地内存与主内存之间的数据更新,实现各线程本地内存的数据操作,可以向主内存中数据一样可以共享。
1未使用volatile关键字
package ThreadVolatile;
import com.sun.jna.platform.win32.FlagEnum;
import com.zx.threadlock.threadDemo;
public class VolatileDemo {
public static void main(String[] args) throws InterruptedException {
Thread1 t1 = new Thread1();
t1.start();
Thread.sleep(300);
t1.isRun(false);
}
}
class Thread1 extends Thread{
public boolean flag = true;
@Override
public void run() {
System.out.println("子线程开始执行");
while(flag) {
}
System.out.println("子线程结束执行");
}
public void isRun(boolean flag) {
this.flag = flag;
}
}
执行结果
线程持续执行,未能结束。isRun方法未能将flag设置为的false的状态共享,主线程未能获得变化,所以一直以true执行,出现线程安全问题。
修改变量flag的关键字volatile
class Thread1 extends Thread{
public volatile boolean flag = true;
@Override
public void run() {
System.out.println("子线程开始执行");
while(flag) {
}
System.out.println("子线程结束执行");
}
public void isRun(boolean flag) {
this.flag = flag;
}
}
执行结果
子线程成功结束
2分析
java内存模型
因为线程之间开始默认为不可见的,所以在线程t1调用isRun方法,将flag设置为false时,主线程没有获取到更新,从而使得主线程一直以flag为true执行,使得子线程无法关闭,在使用volatile关键字后,flag为可见,主内存可以获得子线程中本地内存对flag数据的操作结果。
volatile非原子性
线程三大大特性之一的是原子性,为保证数据的一致性来确保线程安全。volatile主要作用为更新本地内存中的数据,并不会保证操作的原子性。volatile非原子性