synchronized和Lock有什么區(qū)別-創(chuàng)新互聯(lián)

這篇文章主要介紹synchronized和Lock有什么區(qū)別,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比安澤網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式安澤網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋安澤地區(qū)。費用合理售后完善,10余年實體公司更值得信賴。

區(qū)別:1、lock是一個接口,而synchronized是java的一個關(guān)鍵字。2、synchronized在發(fā)生異常時會自動釋放占有的鎖,因此不會出現(xiàn)死鎖;而lock發(fā)生異常時,不會主動釋放占有的鎖,必須手動來釋放鎖,可能引起死鎖的發(fā)生。

在分布式開發(fā)中,鎖是線程控制的重要途徑。Java為此也提供了2種鎖機制,synchronized和lock。

0、synchronized實現(xiàn)原理

Java中每一個對象都可以作為鎖,這是synchronized實現(xiàn)同步的基礎(chǔ):

  • 普通同步方法,鎖是當前實例對象

  • 靜態(tài)同步方法,鎖是當前類的class對象

  • 同步方法塊,鎖是括號里面的對象
    當一個線程訪問同步代碼塊時,它首先是需要得到鎖,當退出或者拋出異常時必須要釋放鎖,那么它是如何來實現(xiàn)這個機制的呢?我們先看一段簡單的代碼:

package cn.alibab.javap;public class SynchronizedTest {

    public synchronized void test1(){

    }    public void test2(){        synchronized (this){

        }
    }
}

利用javap工具(javap是java編譯之后的class文件的分解器)查看生成的class文件信息來分析Synchronized的實現(xiàn)

synchronized和Lock有什么區(qū)別

synchronized和Lock有什么區(qū)別
從上面可以看出,同步代碼塊是使用monitorenter和monitorexit指令實現(xiàn)的,同步方法(在這看不出來需要看JVM底層實現(xiàn))依靠的是方法修飾符上的ACC_SYNCHRONIZED實現(xiàn)。

同步代碼塊:monitorenter指令是在編譯后插入到同步代碼塊的開始位置,monitorexit指令插入到同步代碼塊的結(jié)束位置,JVM需要保證每一個monitorenter都有一個monitorexit與之相對應(yīng)。任何對象都有一個monitor與之相關(guān)聯(lián),當且一個monitor被持有之后,他將處于鎖定狀態(tài)。線程執(zhí)行到monitorenter指令時,將會嘗試獲取對象所對應(yīng)的monitor所有權(quán),即嘗試獲取對象的鎖;【摘自并發(fā)編程藝術(shù)】

同步方法:synchronized方法則會被翻譯成普通的方法調(diào)用和返回指令如:invokevirtual、areturn指令,在VM字節(jié)碼層面并沒有任何特別的指令來實現(xiàn)被synchronized修飾的方法,而是在Class文件的方法表中將該方法的access_flags字段中的synchronized標志位置1,表示該方法是同步方法并使用調(diào)用該方法的對象或該方法所屬的Class在JVM的內(nèi)部對象表示Klass做為鎖對象。(摘自:http://www.cnblogs.com/javaminer/p/3889023.html)

synchronized和lock的區(qū)別

synchronized和Lock有什么區(qū)別
區(qū)別如下:

  • 來源:
    lock是一個接口,而synchronized是java的一個關(guān)鍵字,synchronized是內(nèi)置的語言實現(xiàn);

  • 異常是否釋放鎖:
    synchronized在發(fā)生異常時候會自動釋放占有的鎖,因此不會出現(xiàn)死鎖;而lock發(fā)生異常時候,不會主動釋放占有的鎖,必須手動unlock來釋放鎖,可能引起死鎖的發(fā)生。(所以好將同步代碼塊用try catch包起來,finally中寫入unlock,避免死鎖的發(fā)生。)

  • 是否響應(yīng)中斷
    lock等待鎖過程中可以用interrupt來中斷等待,而synchronized只能等待鎖的釋放,不能響應(yīng)中斷;

  • 是否知道獲取鎖
    Lock可以通過trylock來知道有沒有獲取鎖,而synchronized不能;

  • Lock可以提高多個線程進行讀操作的效率。(可以通過readwritelock實現(xiàn)讀寫分離)

  • 在性能上來說,如果競爭資源不激烈,兩者的性能是差不多的,而當競爭資源非常激烈時(即有大量線程同時競爭),此時Lock的性能要遠遠優(yōu)于synchronized。所以說,在具體使用時要根據(jù)適當情況選擇。

  • synchronized使用Object對象本身的wait 、notify、notifyAll調(diào)度機制,而Lock可以使用Condition進行線程之間的調(diào)度,

//Condition定義了等待/通知兩種類型的方法
Lock lock=new ReentrantLock();
Condition condition=lock.newCondition();...condition.await();...condition.signal();
condition.signalAll();

1、synchronized和lock的用法區(qū)別

synchronized:在需要同步的對象中加入此控制,synchronized可以加在方法上,也可以加在特定代碼塊中,括號中表示需要鎖的對象。

lock:一般使用ReentrantLock類做為鎖。在加鎖和解鎖處需要通過lock()和unlock()顯示指出。所以一般會在finally塊中寫unlock()以防死鎖。

2、synchronized和lock性能區(qū)別

synchronized是托管給JVM執(zhí)行的,
而lock是java寫的控制鎖的代碼。

在Java1.5中,synchronize是性能低效的。因為這是一個重量級操作,需要調(diào)用操作接口,導(dǎo)致有可能加鎖消耗的系統(tǒng)時間比加鎖以外的操作還多。相比之下使用Java提供的Lock對象,性能更高一些。

但是到了Java1.6,發(fā)生了變化。synchronize在語義上很清晰,可以進行很多優(yōu)化,有適應(yīng)自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖等等。導(dǎo)致在Java1.6上synchronize的性能并不比Lock差。官方也表示,他們也更支持synchronize,在未來的版本中還有優(yōu)化余地。

2種機制的具體區(qū)別:
synchronized原始采用的是CPU悲觀鎖機制,即線程獲得的是獨占鎖。獨占鎖意味著其他線程只能依靠阻塞來等待線程釋放鎖。而在CPU轉(zhuǎn)換線程阻塞時會引起線程上下文切換,當有很多線程競爭鎖的時候,會引起CPU頻繁的上下文切換導(dǎo)致效率很低。

而Lock用的是樂觀鎖方式。所謂樂觀鎖就是,每次不加鎖而是假設(shè)沒有沖突而去完成某項操作,如果因為沖突失敗就重試,直到成功為止。樂觀鎖實現(xiàn)的機制就是CAS操作(Compare and Swap)。我們可以進一步研究ReentrantLock的源代碼,會發(fā)現(xiàn)其中比較重要的獲得鎖的一個方法是compareAndSetState。這里其實就是調(diào)用的CPU提供的特殊指令。

現(xiàn)代的CPU提供了指令,可以自動更新共享數(shù)據(jù),而且能夠檢測到其他線程的干擾,而 compareAndSet() 就用這些代替了鎖定。這個算法稱作非阻塞算法,意思是一個線程的失敗或者掛起不應(yīng)該影響其他線程的失敗或掛起的算法。

3、synchronized和lock用途區(qū)別

synchronized原語和ReentrantLock在一般情況下沒有什么區(qū)別,但是在非常復(fù)雜的同步應(yīng)用中,請考慮使用ReentrantLock,特別是遇到下面2種需求的時候。

1.某個線程在等待一個鎖的控制權(quán)的這段時間需要中斷
2.需要分開處理一些wait-notify,ReentrantLock里面的Condition應(yīng)用,能夠控制notify哪個線程
3.具有公平鎖功能,每個到來的線程都將排隊等候

下面細細道來……

先說第一種情況,ReentrantLock的lock機制有2種,忽略中斷鎖和響應(yīng)中斷鎖,這給我們帶來了很大的靈活性。比如:如果A、B 2個線程去競爭鎖,A線程得到了鎖,B線程等待,但是A線程這個時候?qū)嵲谟刑嗍虑橐幚恚褪且恢辈环祷?,B線程可能就會等不及了,想中斷自己,不再等待這個鎖了,轉(zhuǎn)而處理其他事情。這個時候ReentrantLock就提供了2種機制:可中斷/可不中斷
第一,B線程中斷自己(或者別的線程中斷它),但是ReentrantLock不去響應(yīng),繼續(xù)讓B線程等待,你再怎么中斷,我全當耳邊風(synchronized原語就是如此);
第二,B線程中斷自己(或者別的線程中斷它),ReentrantLock處理了這個中斷,并且不再等待這個鎖的到來,完全放棄。

以上是synchronized和Lock有什么區(qū)別的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

網(wǎng)頁題目:synchronized和Lock有什么區(qū)別-創(chuàng)新互聯(lián)
當前URL:http://muchs.cn/article32/coegpc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、云服務(wù)器、自適應(yīng)網(wǎng)站、網(wǎng)站導(dǎo)航軟件開發(fā)、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)