科技快訊
11月16日晚間訊息,攜程CEO孫潔就親子園事件相關進展做最終通報,攜程前人力資源部副總裁施琦、現任人力資源部副總裁馮衛華已被免職。 本文
volatile關鍵字雖然擁有多個線程之間的可見度,但是卻不具備同步性(也就是原子性),可以算上是一個輕量級的synchronized,效能要比synchronized強很多,不會造成阻塞(在很多開源的架構裡,比如netty的底層代碼就大量使用volatile,可見 netty效能一定是非常不錯的。)這裡需要注意:一般volatile用於只針對於多個線程可見的變數操作,並不能代替synchronized的同步功能。 如下案例:
public class VolatileNoAtomic extends Thread { //private static volatile int count; private static AtomicInteger count = new AtomicInteger(0); private static void addCount() { //count++ ; count.incrementAndGet(); System.out.println(Thread.currentThread().getName() + " >>>> " + count); } public void run() { addCount(); } public static void main(String[] args) { VolatileNoAtomic[] arr = new VolatileNoAtomic[100]; for (int i = 0; i < 10; i++) { arr[i] = new VolatileNoAtomic(); } for (int i = 0; i < 10; i++) { arr[i].start(); } }}
列印結果(每一次的列印結果都會是不一樣的):
Thread-1 >>>> 3Thread-2 >>>> 3Thread-0 >>>> 3Thread-3 >>>> 4Thread-4 >>>> 5Thread-5 >>>> 6Thread-6 >>>> 7Thread-7 >>>> 8Thread-8 >>>> 9Thread-9 >>>> 10
樣本總結
volatile關鍵字只具有可見度,沒有原子性。要實現原子性建議使用atomic類的系列對象,支援原子性操作(注意atomic類只保證本身方法原子性,並不保證多次操作的原子性)
如下案例:
public class AtomicUse { private static AtomicInteger count = new AtomicInteger(0); //多個addAndGet在一個方法內是非原子性的,需要加synchronized進行修飾,保證4個addAndGet整體原子性 /**synchronized*/ public synchronized int multiAdd(){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count.addAndGet(1);//+1 count.addAndGet(2);//+3 count.addAndGet(3);//+6 count.addAndGet(4); //+10 也就是一次加10 return count.get(); } public static void main(String[] args) { final AtomicUse au = new AtomicUse(); List<Thread> ts = new ArrayList<Thread>(); for (int i = 0; i < 10; i++) { ts.add(new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+" >>>> "+au.multiAdd()); } })); } for(Thread t : ts){ t.start(); } }}
列印結果:
Thread-0 >>>> 10Thread-9 >>>> 20Thread-8 >>>> 30Thread-7 >>>> 40Thread-6 >>>> 50Thread-5 >>>> 60Thread-4 >>>> 70Thread-3 >>>> 80Thread-2 >>>> 90Thread-1 >>>> 100
多個addAndGet在一個方法內是非原子性的,需要加synchronized進行修飾,保證4個addAndGet整體原子性
原始碼:https://github.com/hfbin/Thread_Socket/tree/master/Thread/sync007