該例子共有4個類,分別是account(賬戶類),bank(取款),company(增款),client(使用者)。bank類會模擬100次取款,每次1000,company類會模擬100次增款,每次1000。使用者初始賬戶為1000,所以正確情況應該是餘額依然為1000。
下面是account源**:
package com.zk;
public
class
account
/** 設定餘額 **/
public
void
setbalance(double balance)
/** 增加餘額 **/
public
synchronized
void
addamount(double amount)catch(interruptedexception e)
tmp += amount;
balance = tmp;
}/** 減少餘額**/
public
synchronized
void
substractamount(double amount)catch(interruptedexception e)
tmp -= amount;
balance = tmp;}}
bank**:
package com.zk;
/** 從銀行中取款 **/
public
class
bank
implements
runnable
@override
public
void
run() }}
company**:
package com.zk;
/** 公司會發工資 **/
public
class
company
implements
runnable
@override
public
void
run() }}
client**:
package com.zk;
public
class
client catch (interruptedexception e) }}
多次執行結果如下:
通過thread.sleep(10)
我們來模擬取款增款時的乙個延時。
在去掉addamount()
和substractamount()
前面的關鍵字synchronized
以後,當我們再次執行,會發現出現了錯誤的結果,而且每次結果不一樣。這是因為jvm是不保證執行緒執行順序,所以每次執行結果不一樣。
而當我們新增上synchronized
關鍵字的時候,這個時候當執行緒a正在執行account
類中標有synchronized
方法的時候,如果有其他執行緒想同時執行synchronized
方法,那麼它將會阻塞直至執行緒a所正在執行的synchronized
方法結束。同一時刻,只能有乙個執行緒執行乙個類中的乙個synchronized
方法。
在實際使用中,可以使用synchronized
來鎖一部分**,而不是整個方法:
synchronized(this)
而且這樣還可以根據需要來鎖定不同的物件,而不是整個類:
private
final object cinemaa = new object();
private
final object cinemab = new object();
/** 影院a銷售票,鎖定cinemaa物件即可 **/
public
void
cinemaaselltickets()
}/** 影院b銷售票,鎖定cinemab物件即可 **/
public
void
clinemabselltickets()
}
java 執行緒 執行緒同步
threadlocal與其它同步機制的比較 threadlocal和其他所有的同步機制都是為了解決多執行緒中的對同一變數的訪問衝突。在普通的同步機制中,是通過對物件加鎖來實現多個執行緒對同一變數的安全訪問的。這時該變數是多個執行緒共享的,使用這種同步機制需要很細緻的分析在什麼時候對變數進行讀寫,什麼...
java同步執行緒
同步執行緒 synchronized方法 乙個類中任何方法都可以定義為synchronized方法以防止多執行緒資料崩潰。當某個物件用synchronized方法修飾時,表明該物件在任一時刻只能由乙個執行緒訪問。宣告方法體的一般格式 modifier synchronized returntype ...
Java 執行緒同步
編寫多執行緒程式,實現生產者 消費者執行緒,並實現執行緒的同步 1 生產者執行緒產生 20個數,消費者執行緒輸出生產者執行緒產生的這 20個數。2 使用執行緒的同步與協調機制使二者達到如此效果 產生乙個數,取出乙個數。public class buffer catch interruptedexce...