Loading

003JUC volatile关键字

内存可见性

概念

​ 指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化。

问题

​ 可见性错误是指当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。

解决

  1. 使用同步来保证对象被安全地发布
  2. 也可以轻量级的volatile 变量

volatile 关键字

概念

一种稍弱的同步机制,即volatile 变量,用来确保将变量的更新操作通知到其他线程。

与 synchronized 比对

  • 对于多线程,不是一种volatile互斥关系
  • volatile不能保证变量状态的原子性操作(比如i++操作)

案例

// volatile 
public class TestVolatile {
	
	public static void main(String[] args) {
		ThreadDemo td = new ThreadDemo();
		new Thread(td).start();
		
		while(true){
			if(td.isFlag()){
				System.out.println("------------------");
				break;
			}
		}
		
	}
}

// 同步机制
public class TestSynchronized {
	
	public static void main(String[] args) {
        // 每个线程会开辟新的内存空间(对于全集变量是复制并线程结束后回写)来执行线程
		ThreadDemo td = new ThreadDemo();
		new Thread(td).start();
		
		while(true){
            synchronized(this) {
                if(td.isFlag()){
                    System.out.println("------------------");
                    break;
                }    
            }
		}
	}
}

class ThreadDemo implements Runnable {
	
    // 定义为volatile 则数据放在公共区域。
	private volatile boolean flag = false;

	@Override
	public void run() {
		
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
		}

		flag = true;
		
		System.out.println("flag=" + isFlag());

	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

}
posted @ 2021-01-07 21:55  TrueBt  阅读(50)  评论(0编辑  收藏  举报