Java™ 教程(併發活性)

併發活性

併發應用程序及時執行的能力被稱爲其活性,本節描述了最多見的活性問題,死鎖,並繼續簡要描述其餘兩個活性問題,飢餓和活鎖。java

死鎖

死鎖描述了兩個或多個線程永遠被阻塞,等待彼此的狀況,這是一個例子。git

Alphonse和Gaston是朋友,是禮貌的忠實信徒,禮貌的一個嚴格規則是,當你向朋友鞠躬時,你必須一直鞠躬,直到你的朋友有機會還禮,不幸的是,這條規則沒有考慮到兩個朋友可能同時互相鞠躬的可能性,這個示例應用程序Deadlock模擬了這種可能性:github

public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s"
                + "  has bowed to me!%n", 
                this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            public void run() { alphonse.bow(gaston); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow(alphonse); }
        }).start();
    }
}

Deadlock運行時,兩個線程在嘗試調用bowBack時極有可能會阻塞,兩個阻塞都不會結束,由於每一個線程都在等待另外一個線程退出bowsegmentfault

飢餓和活鎖

飢餓和活鎖問題遠沒有死鎖常見,但仍然是每一個併發軟件設計人員可能遇到的問題。併發

飢餓

飢餓描述了一種狀況,即線程沒法得到對共享資源的按期訪問,而且沒法取得進展,當「貪婪」線程使共享資源長時間不可用時會發生這種狀況。例如,假設一個對象提供了一個一般須要很長時間才能返回的同步方法,若是一個線程頻繁地調用此方法,其餘也須要頻繁同步訪問同一對象的線程將常常被阻塞。this

活鎖

一個線程常常響應另外一個線程的操做,若是另外一個線程的操做也是對另外一個線程的操做的響應,則可能致使活鎖。與死鎖同樣,活鎖線程沒法取得進一步進展,可是,線程不會被阻塞 — 它們只是太忙於迴應彼此而沒法繼續工做。這至關於兩個試圖在走廊裏互相經過的人:Alphonse向左移動讓Gaston經過,而Gaston向右移動讓Alphonse經過,看到他們仍然互相阻塞,Alphone向右移動,而Gaston向左移動,他們還在互相阻塞,因此...。線程


上一篇:同步

下一篇:守護阻塞

相關文章
相關標籤/搜索