當前位置:才華齋>計算機>java語言>

Java執行緒同步的方法

java語言 閱讀(3.12W)

執行緒的同步是Java多執行緒程式設計的難點,往往開發者搞不清楚什麼是競爭資源、什麼時候需要考慮同步,怎麼同步等等問題,當然,這些問題沒有很明確的答案,但有些原則問題需要考慮,是否有競爭資源被同時改動的問題?以下僅供參考!

Java執行緒同步的方法

對於同步,在具體的Java程式碼中需要完成一下兩個操作:把競爭訪問的資源標識為private;同步哪些修改變數的程式碼,使用synchronized關鍵字同步方法或程式碼。當然這不是唯一控制併發安全的途徑。synchronized關鍵字使用說明synchronized只能標記非抽象的方法,不能標識成員變數。為了演示同步方法的使用,構建了一個信用卡賬戶,起初信用額為100w,然後模擬透支、存款等多個操作。顯然銀行賬戶User物件是個競爭資源,而多個併發操作的是賬戶方法oper(int x),當然應該在此方法上加上同步,並將賬戶的餘額設為私有變數,禁止直接訪問。

/**

* Java執行緒:執行緒的同步

*

* @author leizhimin 2009-11-4 11:23:32

*/

public class Test {

public static void main(String[] args) {

User u = new User(“張三”, 100);

MyThread t1 = new MyThread(“執行緒A”, u, 20);

MyThread t2 = new MyThread(“執行緒B”, u, -60);

MyThread t3 = new MyThread(“執行緒C”, u, -80);

MyThread t4 = new MyThread(“執行緒D”, u, -30);

MyThread t5 = new MyThread(“執行緒E”, u, 32);

MyThread t6 = new MyThread(“執行緒F”, u, 21);

t();

t();

t();

t();

t();

t();

}

}

class MyThread extends Thread {

private User u;

private int y = 0;

MyThread(String name, User u, int y) {

super(name);

this.u = u;

this.y = y;

}

public void run() {

(y);

}

}

class User {

private String code;

private int cash;

User(String code, int cash) {

= code;

= cash;

}

public String getCode() {

return code;

}

public void setCode(String code) {

= code;

}

/**

* 業務方法

* @param x 新增x萬元

*/

public synchronized void oper(int x) {

try {

p(10L);

+= x;

tln(entThread()。getName() + “執行結束,增加” + x + “”,“當前使用者賬戶餘額為:” + cash);

p(10L);

} catch (InterruptedException e) {

tStackTrace();

}

}

@Override

public String toString() {

return “User{” + “code=‘” + code + ’‘’ + “, cash=” + cash +‘}’;

}

}

輸出結果:執行緒A執行結束,增加“20”,當前使用者賬戶餘額為:120.

執行緒F執行結束,增加“21”,當前使用者賬戶餘額為:141.

執行緒E執行結束,增加“32”,當前使用者賬戶餘額為:173.

執行緒C執行結束,增加“-80”,當前使用者賬戶餘額為:93.

執行緒B執行結束,增加“-60”,當前使用者賬戶餘額為:33.

執行緒D執行結束,增加“-30”,當前使用者賬戶餘額為:3.

Process finished with exit code 0反面教材,不同步的情況,也就是去掉oper(int x)方法的synchronized修飾符,然後執行程式,結果如下:執行緒A執行結束,增加“20”,當前使用者賬戶餘額為:61.

執行緒D執行結束,增加“-30”,當前使用者賬戶餘額為:63.

執行緒B執行結束,增加“-60”,當前使用者賬戶餘額為:3.

執行緒F執行結束,增加“21”,當前使用者賬戶餘額為:61.

執行緒E執行結束,增加“32”,當前使用者賬戶餘額為:93.

執行緒C執行結束,增加“-80”,當前使用者賬戶餘額為:61.

Process finished with exit code 0很顯然,上面的結果是錯誤的,導致錯誤的原因是多個執行緒併發訪問了競爭資源u,並對u的屬性做了改動。可見同步的重要性。注意:通過前文可知,執行緒退出同步方法時將釋放掉方法所屬物件的鎖,但還應該注意的是,同步方法中還可以使用特定的方法對執行緒進行排程。這些方法來自於ct類,void notify()。

喚醒在此物件監視器上等待的`單個執行緒。

void notifyAll()

喚醒在此物件監視器上等待的所有執行緒。

void wait()

導致當前的執行緒等待,直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法。

void wait(long timeout)

導致當前的執行緒等待,直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量。

void wait(long timeout, int nanos)

導致當前的執行緒等待,直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者其他某個執行緒中斷當前執行緒,或者已超過某個實際時間量。