當前位置:才華齋>IT認證>JAVA認證>

Java執行緒同步的方法大綱

JAVA認證 閱讀(1.41W)

執行緒的同步是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() 方法,或者其他某個執行緒中斷當前執行緒,或者已超過某個實際時間量。