《Java並發編程實戰》第十章 避免活躍性危急 讀書筆記

來源:互聯網
上載者:User

標籤:yacc   eth   活躍   target   from   art   爭奪   not   資訊   


一、死結所謂死結: 是指兩個或兩個以上的進程在運行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。

百科百科

當兩個以上的運算單元,兩方都在等待對方停止執行,以取得系統資源,可是沒有一方提前退出時。這樣的狀況。就稱為死結。維基百科


1. 順序死結最少有兩個鎖。一個線程擷取到A鎖須要擷取B鎖才幹進行操作,而另外一個線程擷取到了B鎖,須要擷取A鎖才幹運行操作,這樣的情況下easy出現順序死結。


public class LeftRightDeadlock {private final Object left = new Object();private final Object right = new Object();public void leftRight() {synchronized (left) {synchronized (right) {// doSomething();}}}public void rightLeft() {synchronized (right) {synchronized (left) {// doSomething();}}}}



2. 動態鎖順序死結
public void transferMoney(Account fromAccount, Account toAccount, DollarAmount anount)throws InsufficientResourcesException {synchronized (fromAccount) {synchronized (toAccount) {if (fromAccount.getBalance().compareTo(amount) < 0) {throw new InsufficientResourcesException();} else {fromAccount.debit(anount);toAccount.credit(anount);}}}}

A: transferMoney(myAccount, yourAccount, 10);
B: transferMoney(yourAccount, myAccount, 20);

由外部傳入的變數全部鎖的條件,可是由以上傳入的變數能夠看到,這樣的情況下會出現一個線程先擷取myAccount鎖在申請yourAccount鎖,而另外一個線程相反先擷取yourAccount鎖在申請myAccount鎖。
private static final Object tieLock = new Object();public void transferMoney(final Account fromAccount, final Account toAccount, final DollarAmount anount)throws InsufficientResourcesException {class Helper{    public void transfer() throws InsufficientResourcesException {        if (fromAccount.getBalance().compareTo(amount) < 0){        throw new InsufficientResourcesException();        } else{fromAccount.debit(anount);toAccount.credit(anount);        }    }}int fromHash = System.identityHashCode(fromAccount);int toHash = System.identityHashCode(toAccount);if (fromHash < toHash){    synchronized (fromAccount){        synchronized (toAccount) {            new Helper().transfer();        }    }} else if (fromHash >  toHash){    synchronized (toAccount){        synchronized (fromAccount) {            new Helper().transfer();        }    }} else {    synchronized (tieLock) {        synchronized (fromAccount) {            synchronized (toAccount) {                new Helper().transfer();            }        }    }}}

3. 在協作對象之間發生的死結
class Taxi {private Point location, destination;private final Dispatcher dispatcher;public Taxi(Dispatcher dispatcher) {    this.dispatcher = dispatcher;}public synchronized Point getLocation(){    return location;}public synchronized void setLocation(Point location){    this.location = location;    if (location.equals(destination)){        dispatcher.notifyAvaliable(this);    }}} class Dispatcher {private final Set<Taxi> taxis;private final Set<Taxi> avaliableTaxis;public Dispatcher(){    taxis = new HashSet<Taxi>();    avaliableTaxis = new HashSet<Taxi>();}public synchronized void notifyAvaliable(Taxi taxi) {    avaliableTaxis.add(taxi);}public synchronized Image getImage(){    Image image = new Image();    for (Taxi t :taxis){        image.drawMarker(t.getLocation());    }    return image;}}

4. 開放調用 -- 待填充
5. 資源死結外部鎖常被忽視而導致死結,比如資料庫的鎖
二、死結的避免與診斷1. 支援定時的死結存在一些預防死結的手段。比方Lock的tryLock,JDK 7中引入的Phaser等。

2. 通過線程轉儲資訊來分析死結通過Dump線程的StackTrace,比如linux下運行命令 kill -3 <pid>,或者jstack –l <pid>,或者使用Jconsole串連上去查看線程的StackTrace。由此來診斷死結問題。



三、其它活躍性危急1. 饑餓2. 糟糕的響應性3. 活鎖


四、鎖的使用使用支援CAS的資料結構。避免使用鎖,如:AtomicXXX、ConcurrentMap、CopyOnWriteList、ConcurrentLinkedQueue死結常常是無法全然避免的,鴕鳥策略被非常多基礎架構所採用。存在檢測死結的辦法

五、參考資料:《溫紹錦 - Java並發程式設計教程》


《Java並發編程實戰》第十章 避免活躍性危急 讀書筆記

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.