Java多線程Violate(可見性)Atomic(原子性)

violate保證了可見性可是不能保證原子性的狀況;安全

解決了vialate關鍵字不能保證原子性(線程安全)併發

要求,一個線程去將count+1000的操做,輸出1000,2000~~~~10000ide

使用vialate打印出來的很明顯不符合要求,vialate只能保證可見性,不能保證原子性。atom

violate保證了可見性緣由:當關鍵字使用了violate事後,線程數據一更新就會寫到主內存中去,並讓其餘線程的引用失效。好比A線程和B線程都引用了violate修飾的變量,當A線程更改事後,會讓B線程中的變量失效,當B要用變量時只能從主內存中去取,因此保證了可見性(不能保證原子性的緣由:下面)線程

violate保證了可見性可是不能保證原子性的緣由:假如A線程讀取到的數是0,在執行1000次++操做中(++不是原子性操做,會執行三次,取值、+一、賦值),其中一次出現阻塞的狀況,並不會去讓其餘線程的值失效,因此其餘的線程有可能拿到的不是最後的執行結果1000。code

使用Atomic併發包就能保證,注意必需要加static修飾,由於加了static,表示這個就是單例,只有一個,若是不加static的話,每一次都是新的,都是1000內存

class VolatileNoAtomic extends Thread {
//	private static volatile int count = 0;
	private static AtomicInteger atomicInteger=new AtomicInteger(0);
	@Override
	public void run() {
		for (int i = 0; i < 1000; i++) {
//			count++;
			atomicInteger.incrementAndGet(); //count++;
		}
		System.out.println(getName() + "-----" + atomicInteger);
	}
}

public class VolatileNoAtomicDemo {

	public static void main(String[] args) {
      // 初始化10個線程
		VolatileNoAtomic[] volatileNoAtomic=	new VolatileNoAtomic[10];
		for (int i = 0; i < volatileNoAtomic.length; i++) {
			//建立每個線程
			volatileNoAtomic[i]=new VolatileNoAtomic();
		}
		for (int i = 0; i < volatileNoAtomic.length; i++) {
			//啓動每個線程
			volatileNoAtomic[i].start();
		}
	}
}

依次輸出1000,2000~~~10000,可是線程的順序不必定同樣,由於線程的優先級由CPU來選擇rem

相關文章
相關標籤/搜索