java基礎:執行緒同步

十五樓亮哥發表於2015-02-03

一:先看程式

public class Timer1 {
	private static int num = 0;

	public void add(String name) {
		num++;
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name + ",你是第" + num + "個使用Timer的執行緒");

	}
}


public class TestSync1 implements Runnable{

	Timer1 timer = new Timer1();
	@Override
	public void run() {
		timer.add(Thread.currentThread().getName());
	}
	
	
	public static void main(String[] args) {
		TestSync1 test = new TestSync1();
		Thread t1 = new Thread(test);
		Thread t2 = new Thread(test);
		t1.start();
		t2.start();
	}

}

看輸出結果:

Thread-0,你是第2個使用Timer的執行緒
Thread-1,你是第2個使用Timer的執行緒

結果明顯有問題:

這是因為兩個執行緒訪問的是同一個Timer物件,其中一個執行緒呼叫Timer的add方法時,num++,這個時候,另外一個執行緒也有可能呼叫add方法,num又++,然後執行緒1輸出,執行緒2輸出,輸出的是同一個num = 2


二:解決辦法

add方法上加上synchronized關鍵字:public synchronized void add(String name){

或者在timer內部,執行程式碼塊

synchronized(this){  
	num++;
	try {
		Thread.sleep(1);
	} catch (InterruptedException e) {
				e.printStackTrace();
	}
	System.out.println(name + ",你是第" + num + "個使用Timer的執行緒");

}

這兩種方法,道理是一個的,都是實現鎖定Timer物件。


相關文章