轉載請標明出處: http://blog.csdn.net/zhangxingping
前面說到了Java中的同步問題。下面通過一個小小的執行個體程式來示範Java中的同步方法。其中對前文提到的Counter類做了稍微的修改。
public class Counter {private int c = 0;public void increment() {System.out.println("before increment, c = " + c);c++;try {Thread.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("after increment, c = " + c);}public void decrement() {System.out.println("before decrement, c = " + c);c--;try {Thread.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("after decrement, c = " + c);}public int value() {return c;}}
在上面的Counter類的實現中,分別對increment和decrement方法中增加了sleep(5)的調用,這樣做的目的是為了放大兩個線程對同一對象的方法調用時的交錯效果。
下面是兩個線程。在ThreadA中調用了10次increment()方法;在ThreadB中調用了10次decrement()方法。
Thread:
public class ThreadA implements Runnable {private Counter c;public ThreadA(Counter c) {this.c = c;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {this.c.increment();}}}
ThreadB:
public class ThreadB implements Runnable {private Counter c;public ThreadB(Counter c) {this.c = c;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {this.c.decrement();}}}
主程式如下:其中產生了兩個線程threadA和ThreadB,他們共用Counter c。
public class Main {public static void main(String[] args) {Counter c = new Counter();ThreadA a = new ThreadA(c);ThreadB b = new ThreadB(c);Thread threadA = new Thread(a);Thread threadB = new Thread(b);threadA.start();threadB.start();}}
執行上面的代碼,可能的結果如下:
before increment, c = 0
before decrement, c = 1
after increment, c = 0
before increment, c = 0
after decrement, c = 1
before decrement, c = 1
after increment, c = 0
before increment, c = 0
after decrement, c = 1
before decrement, c = 1
after increment, c = 0
before increment, c = 0
after decrement, c = 1
before decrement, c = 1
after increment, c = 0
before increment, c = 0
after decrement, c = 1
before decrement, c = 1
after increment, c = 0
before increment, c = 0
after decrement, c = 1
before decrement, c = 1
after increment, c = 0
before increment, c = 0
after increment, c = 1
before increment, c = 1
after decrement, c = 2
before decrement, c = 2
after decrement, c = 1
before decrement, c = 1
after increment, c = 0
before increment, c = 0
after increment, c = 1
before increment, c = 1
after decrement, c = 2
before decrement, c = 2
after increment, c = 1
after decrement, c = 1
before decrement, c = 1
after decrement, c = 0
從上面的輸出結果中我們不難看出出現了嚴重的交錯現象。 在increment或者是decrement方法中輸出before和after本應該是成對連續出現的。但輸出結果卻不是如此。
將上面代碼的increment()和decrement()方法用synchronized 修飾後,重新運行該程式,輸出結果如下:
before increment, c = 0
after increment, c = 1
before increment, c = 1
after increment, c = 2
before decrement, c = 2
after decrement, c = 1
before increment, c = 1
after increment, c = 2
before decrement, c = 2
after decrement, c = 1
before decrement, c = 1
after decrement, c = 0
before decrement, c = 0
after decrement, c = -1
before decrement, c = -1
after decrement, c = -2
before increment, c = -2
after increment, c = -1
before decrement, c = -1
after decrement, c = -2
before decrement, c = -2
after decrement, c = -3
before decrement, c = -3
after decrement, c = -4
before decrement, c = -4
after decrement, c = -5
before increment, c = -5
after increment, c = -4
before decrement, c = -4
after decrement, c = -5
before increment, c = -5
after increment, c = -4
before increment, c = -4
after increment, c = -3
before increment, c = -3
after increment, c = -2
before increment, c = -2
after increment, c = -1
before increment, c = -1
after increment, c = 0
這樣輸出結果和沒有增加synchronized修飾符時的大不相同:單獨一次的increment和decrement方法並沒有出現交錯的現象。只是連續10次的increment()和decrement ()有交錯。
至少,我們從上面的執行個體程式中可以看到synchronized方法的作用了。
另外,我們還可以使用同步語句(也就是使用Counter對象的同步鎖)來代替上面的同步方法,其效果是一樣的。有興趣的網友可以自己嘗試一下。