volatile與可見性

可見性

    一句話歸納可見性ide

    一個線程修改了共享變量, 其餘線程能夠當即知道this

 

下面經過2段代碼, 看一看 volatile 的做用:spa

1. 未經 volatile 修飾的共享變量 stop.net

/**
 * @author 宋挺
 */
public class VolatileDemo1 implements Runnable {
	// 共享變量
	private boolean stop = false;

	// 修改共享變量
	public void stop() {
		this.stop = true;
	}

	// 線程體
	@Override
	public void run() {
		while (!stop) {
		}
		System.out.println("子程序 stoped");
	}

	public static void main(String[] args) throws InterruptedException {
		VolatileDemo1 vd = new VolatileDemo1();
		// 新建態
		Thread subThread = new Thread(vd);
		// 就緒態
		subThread.start();
		// 在主線程調用 stop() 方法以前, 保證子線程先啓動, 進入運行狀態
		Thread.sleep(10);
		// 主線程調用 stop() 方法, 將共享變量 stop 修改成 true
		vd.setStop();
	}
}

 

運行這段代碼時, 能夠發現:線程

無輸出code

這說明子線程 subThread 的 run() 方法一直處於死循環中, stop 值爲 false, 可是明明在主線程修改了 stop 爲 true 啊blog

這是由於在主線程只是在其工做內存修改了共享變量的副本, 而主內存的共享變量沒有被及時更新, 因此其餘線程觀察不到這個修改動做內存

 

2. 用 volatile 修飾共享變量 stopget

/**
 * @author 宋挺
 */
public class VolatileDemo1 implements Runnable {
	// 用 volatile 修飾共享變量
	private volatile boolean stop = false;

	// 修改共享變量
	public void stop() {
		this.stop = true;
	}

	// 線程體
	@Override
	public void run() {
		while (!stop) {
		}
		System.out.println("子程序 stoped");
	}

	public static void main(String[] args) throws InterruptedException {
		VolatileDemo1 vd = new VolatileDemo1();
		// 新建態
		Thread subThread = new Thread(vd);
		// 就緒態
		subThread.start();
		// 在主線程調用 stop() 方法以前, 保證子線程先啓動, 進入運行狀態
		Thread.sleep(10);
		// 主線程調用 stop() 方法, 將共享變量 stop 修改成 true
		vd.setStop();
	}
}

 

運行這段代碼時, 能夠發現:io

    輸出: 子程序 stoped

這說明主線程在修改共享變量後, 子線程在工做內存中更新了共享變量的最新值

因而可知, volatile 能夠實現可見性

 

其餘實現可見性的方式

相關文章
相關標籤/搜索