volatile特性
- 保证可见性
- 禁止重排序
- 不保证原子性
线程可见性问题
/**
* 测试volatile关键值
*/
class ThreadVolatileDemo extends Thread{
public boolean flag = true;
public void run() {
System.out.println("开始执行子线程...");
while (flag) {
}
System.out.println("线程停止");
}
public void setRuning(boolean flag) {
this.flag = flag;
}
}
public class ThreadVolatile {
public static void main(String[] args) throws InterruptedException {
ThreadVolatileDemo threadVolatileDemo = new ThreadVolatileDemo();
threadVolatileDemo.start();
Thread.sleep(3000);
threadVolatileDemo.setRuning(false);
System.out.println("flag已经设置成false");
System.out.println(threadVolatileDemo.flag);
}
}
问题分析
虽然修改了flag ,但是仍会出现死循环。原因:值是不可见,线程读取到的值都是副本。解决办法使用Volatile关键字将解决线程之间可见性, 强制线程每次读取该值的时候都去“主内存”中取值。
public volatile boolean flag = false;
volatile能解决原子性问题?
volatile能解决线程可见性问题,但是原子性却无法解决,如i++操作;