volatile,synchronized,ReentrantLock

synchronized

實現機制:反編譯以後monitor
優化:自旋鎖,適應自旋鎖,輕量級鎖等
所謂自旋鎖,就是讓該線程等待一段時間,不會被立即掛起,看持有鎖的線程是否會很快釋放鎖。怎麼等待呢?執行一段無意義的循環即可(自旋)。
雖然可以避免線程切換帶來的開銷,但是佔用處理器時間

volatile

原子性:一個操作或者多個操作 要麼全部執行並且執行的過程不會被任何因素打斷,要麼就都不執行。(volatile是無法保證複合操作的原子性)
可見性:當多個線程訪問同一個變量時,一個線程修改了這個變量的值,其他線程能夠立即看得到修改的值。(Java提供了volatile來保證可見性)
有序性:程序執行的順序按照代碼的先後順序執行。(Java提供volatile來保證一定的有序性)
使用它必須滿足如下兩個條件:

對變量的寫操作不依賴當前值;
該變量沒有包含在具有其他變量的不變式中。

volatile經常用於兩個場景:狀態標記、double check

ReentrantLock

AQS,AbstractQueuedSynchronizer,即隊列同步器。
AQS使用一個int類型的成員變量state來表示同步狀態,當state>0時表示已經獲取了鎖,當state = 0時表示釋放了鎖。它提供了三個方法(getState()、setState(int newState)、compareAndSetState(int expect,int update))來對同步狀態state進行操作,當然AQS可以確保對state的操作是安全的。
AQS通過內置的FIFO同步隊列來完成資源獲取線程的排隊工作,如果當前線程獲取同步狀態失敗(鎖)時,AQS則會將當前線程以及等待狀態等信息構造成一個節點(Node)並將其加入同步隊列,同時會阻塞當前線程,當同步狀態釋放時,則會把節點中的線程喚醒,使其再次嘗試獲取同步狀態。
該隊列就是CLH同步隊列。CLH同步隊列是一個FIFO雙向隊列,AQS依賴它來完成同步狀態的管理

    private Node addWaiter(Node mode) {
        Node node = new Node(mode);

        for (;;) {
            Node oldTail = tail;
            if (oldTail != null) {
                //尾節點不爲null就添加到尾節點的next(CAS)
                U.putObject(node, Node.PREV, oldTail);
                if (compareAndSetTail(oldTail, node)) {
                    oldTail.next = node;
                    return node;
                }
            } else {
                //尾節是null就初始化整個隊列
                initializeSyncQueue();
            }
        }
    }

前面提到ReentrantLock提供了比synchronized更加靈活和強大的鎖機制,那麼它的靈活和強大之處在哪裏呢?他們之間又有什麼相異之處呢?
首先他們肯定具有相同的功能和內存語義。
與synchronized相比,ReentrantLock提供了更多,更加全面的功能,具備更強的擴展性。例如:時間鎖等候,可中斷鎖等候,鎖投票。
ReentrantLock還提供了條件Condition,對線程的等待、喚醒操作更加詳細和靈活,所以在多個條件變量和高度競爭鎖的地方,ReentrantLock更加適合(以後會闡述Condition)。
ReentrantLock提供了可輪詢的鎖請求。它會嘗試着去獲取鎖,如果成功則繼續,否則可以等到下次運行時處理,而synchronized則一旦進入鎖請求要麼成功要麼阻塞,所以相比synchronized而言,ReentrantLock會不容易產生死鎖些。
ReentrantLock支持更加靈活的同步代碼塊,但是使用synchronized時,只能在同一個synchronized塊結構中獲取和釋放。注:ReentrantLock的鎖釋放一定要在finally中處理,否則可能會產生嚴重的後果。
ReentrantLock支持中斷處理,且性能較synchronized會好些。

條件Condition說明(http://blog.csdn.net/chenssy/article/details/69279356)一個有頭結點和尾節點的單向隊列

發佈了223 篇原創文章 · 獲贊 23 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章