java-多線程深入(六)鎖

來源:互聯網
上載者:User

標籤:java   多線程   

java多線程中提供的鎖:synchronized和lock。

(一)synchronized

1、synchronized的使用

每個對象都內建鎖,鎖可以同步執行個體方法(this是對象鎖)、靜態方法(class是對象鎖)、方法塊(synchronized參數是對象鎖)

下面是鎖住執行個體方法:

public synchronized void add(){        a++;    }
使用注意點:

(1)Object的wait、notify和notifyAll使用時需在代碼外層加鎖,等待和喚醒鎖必須相同,使用的鎖不能發生改變,不然會拋出IllegalMonitorStateException異常

/** * 線程等待喚醒測試 *  * @author peter_wang * @create-time 2014-10-9 下午2:50:36 */public class ThreadNotifyTest {    private static Integer num = new Integer(0);    /**     * @param args     */    public static void main(String[] args) {        final Thread thead1 = new Thread() {            @Override            public void run() {                synchronized (num) {                    try {                        sleep(2000);                        num.wait();                        System.out.println("解鎖成功");                    }                    catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        };        thead1.start();        Thread thead2 = new Thread() {            @Override            public void run() {                try {                    sleep(1000);// num = new Integer(1);  //A                    num++;//B                }                catch (InterruptedException e) {                    e.printStackTrace();                }            }        };        thead2.start();    }}
無論執行A或B,改變了鎖num後,wait執行的時候會拋出IllegalMonitorStateException異常。
對wait、notify加鎖是為了保證它們在執行中的原子性。

(2)使用的鎖盡量是不可變對象,使用private final Object對象,可變化的對象可能導致不可預知的後果,如wait的問題。

(3)synchronized鎖住地區盡量減少,提高效能。

2、synchronized原理探究

(1)線程狀態

當多個線程同時請求某個對象監視器時,對象監視器會設定幾種狀態用來區分請求的線程: 
Contention List:所有請求鎖的線程將被首先放置到該競爭隊列 
Entry List:Contention List中那些有資格成為候選人的線程被移到Entry List,降低對Contention List的爭用

Wait Set:那些調用wait方法被阻塞的線程被放置到Wait Set 

OnDeck:任何時刻最多隻能有一個線程正在競爭鎖,該線程稱為OnDeck Owner:獲得鎖的線程稱為Owner !Owner:釋放鎖的線程
(2)鎖類型

公平鎖和非公平鎖

公平鎖:每個線程取得調度的幾率是一樣的

非公平鎖:每個線程取得的調度幾率不同,是公平鎖吞吐率的5-10倍

自旋鎖和阻塞鎖

自旋鎖:線程阻塞調度過程設計到操作linux核心線程,需要在使用者態和核心態之間切換狀態,效能消耗比較大,自旋機制讓請求調度的線程內部自迴圈,不切換狀態等待一段時間,若仍然未能擷取調度機會再轉換鎖類型

阻塞鎖:阻塞鎖線上程競爭時,無擷取到調度的線程直接進入阻塞隊列

多種阻塞鎖類型

偏向鎖:在大多數情況下,鎖都存在於單線程中,為了讓線程獲得鎖減少效能代價,同一線程多次重入,不會執行CAS操作,直到遇見多線程競爭,轉換成其他類型

輕量鎖:偏向鎖的升級版或者直接設定系統不使用偏向鎖直接進入輕量鎖,比偏向鎖多了步CAS操作,當前若鎖未被其他線程鎖住即可使用,操作失敗進入自旋鎖

重量鎖:完整的阻塞鎖狀態,對象監視器(Monitor),由自旋鎖逾時升級而成

鎖的進化過程:偏向鎖—>輕量鎖—>自旋鎖—>重量鎖

(3)總結

synchronized執行時,優先使用偏向鎖或輕量鎖提升效能,碰到多線程鎖住現象,進入自旋狀態,等待未果進入重量鎖階段,阻塞線程,放入阻塞隊列,切換線程狀態。


(二)Lock

1、ReentrantLock的使用

private ReentrantLock mlock = new ReentrantLock();@Override    public void write() {        mlock.lock();        try {            long startTime = System.currentTimeMillis();            System.out.println("開始往這個buff寫入資料…");            for (;;)// 類比要處理很長時間            {                if (System.currentTimeMillis() - startTime > Integer.MAX_VALUE)                    break;            }            System.out.println("終於寫完了");        }        finally {            mlock.unlock();        }    }
ReentrantLock在lock的時候鎖住執行個體對象,必須在finally中unlock解鎖,防止異常拋出未解鎖。

2、ReentrantLock原理分析

ReentrantLock中的操作都是基於Sync,Sync繼承自AbstractQueuedSynchronizer。

AbstractQueuedSynchronizer通過構造一個基於阻塞的CLH隊列容納所有的阻塞線程,而對該隊列的操作均通過Lock-Free(CAS)操作,但對已經獲得鎖的線程而言,ReentrantLock實現了偏向鎖的功能。


(三)synchronized和ReentrantLock對比

1、效能上synchronized是native方法效能最佳化較多,ReentrantLock是java層實現效能不一定很好。

2、ReentrantLock提供了更多功能,如公平鎖和非公平鎖設定等,但是需要使用finally解鎖。

3、在普通情況下使用synchronized,在業務複雜需要使用ReentrantLock特殊功能的才使用ReentrantLock。


著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

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.