在java併發編程學習之基礎概念提到,多線程的劣勢之一,有個線程安全問題,如今看看下面的例子。java
public class NotSafeDemo { private int num = 0; public void add(int value) { try { num = num + value; Thread.sleep(100); System.out.println("num:" + num); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { NotSafeDemo synchronizeDemo = new NotSafeDemo(); AddThread1 addThread1 = new AddThread1(synchronizeDemo); AddThread2 addThread2 = new AddThread2(synchronizeDemo); addThread1.start(); addThread2.start(); } } class AddThread1 extends Thread { NotSafeDemo synchronizeDemo; public AddThread1(NotSafeDemo synchronizeDemo) { this.synchronizeDemo = synchronizeDemo; } @Override public void run() { synchronizeDemo.add(1); } } class AddThread2 extends Thread { NotSafeDemo synchronizeDemo; public AddThread2(NotSafeDemo synchronizeDemo) { this.synchronizeDemo = synchronizeDemo; } @Override public void run() { synchronizeDemo.add(2); } }
運行結果以下:算法
爲何會不安全呢,在java併發編程學習之基礎概念提過,兩個線程共享一個進程的資源,也就是說,num這個值,是共享的,在還沒輸出num的時候,已經被第二個線程,改爲3,因此兩次輸出都是3。那麼,該怎麼解決呢,很簡單,在方法前加個同步鎖synchronized。編程
synchronized public void add(int value) { try { int temp = num; num = num + value; Thread.sleep(100); System.out.println(value + "+" + temp + "=" + num); } catch (InterruptedException e) { e.printStackTrace(); } }
運行結果以下:segmentfault
有兩種狀況,是由於看誰先搶佔鎖,可是輸出的算法結果是正確的。安全