摘要:備注整理一些同步技術,方便日后回顧。單機多線程情況解讀層面的同步技術,字節碼實現。能夠響應中斷,讓等待狀態的線程停止等待。每個子線程執行完畢以后,執行函數,字段減,直到字段變為。
備注:整理一些同步技術,方便日后回顧。目前技術還在學習中,了解到同步方面的新知識會補充到本文。
單機多線程情況:
synchronized
1、解讀:
(1)jvm層面的同步技術,字節碼實現。當代碼執行出現問題的時候(比如說拋出異常),JVM會自動釋放鎖,讓其他阻塞的線程繼續執行 (2)可重入的:當線程已經獲取鎖對象,并且再次進入同步塊,把鎖的計數器+1,當執行monitorexit時,把鎖的計數器-1,當計數器為0為止,對象被釋放
2、使用情況:
(1)實例對象作為鎖對象:對象實例可能有多個,因此如果不能保證對象單例的情況下,同步可能會出現問題。 (2)類對象作為鎖對象:每個類只有1個類對象。 (3)靜態**同步方法:使用實例對象作為鎖 (4)成員同步方法:使用類對象作為鎖
3、注意事項:
(1)盡量減少同步的范圍,提高程序并發性,減少死鎖的可能性 (2)使用Class類對象和實例對象的區別 (3)靜態方法和非靜態方法進行同步的區別
Lock接口
1、解讀:
(1)Lock接口的同步更為靈活,使用起來也復雜一些 (2)可以設置等待時間,在線程請求鎖的時候,如果超過等待時間,則線程停止等待。 (4)Lock能夠響應中斷,讓等待狀態的線程停止等待。 (5)API提供返回值,知道線程是否成功獲取鎖 (6)常用的實現類:ReentrantLock
2、使用情況:線程需要支持中斷、查看線程是否成功獲得鎖
3、注意事項:
(1)代碼層面實現的鎖機制,遇到異常情況,JVM不會自動釋放鎖。使用lock(),必須使用unlokc()
ReentrantLock
1、解讀:
(1)使用AQS框架實現、實現了Lock接口 (2)排他鎖,只有一個線程能獲取并使用資源 (3)構造方法提供一個可選的公平參數,公平與非公平有何區別,所謂公平就是嚴格按照FIFO的順序獲取鎖,非公平全按程序員自己設計規則來獲取鎖,比如可以根據優先級,也可以按照運行次數等規則來選擇
(4)可以綁定多個Condition對象(Condition對象指的是,當線程獲得鎖,進入同步塊以后,還需要滿足Condition對象的條件,否則仍然會掛起等待,直到其他線程喚醒)
CountDownLatch
1、解讀:
(1)使用AQS框架實現 (2)共享鎖,可以有多個線程同時持有該鎖 (3)任務分成N個任務執行,state字段初始化為N。開始執行任務,調用線程調用await()函數掛起。每個子線程執行完畢以后,執行countDown()函數,state字段減1,直到字段變為0。調用線程從CountDown()函數返回,繼續后續動作。
2、使用情況:
3、注意事項:
wait()、Notify()
1、解讀:
(1)調用對象的wait()方法,會將持有該對象的線程掛起,直到有別的線程調用這個對象的notify()方法
join()
1、解讀:
(1)在B線程中調用A線程的Join方法,則B會等待A線程執行完畢,再往下執行
cas算法
1、解讀:
(1)使用重試的方式,樂觀鎖的一種實現
2、使用場景:
(1)AtomicInteger
Semaphore
1、解讀:
(1)利用AQS實現。 (2)共享鎖,可以有多個線程同時持有該鎖 (3)內部維護一個“許可集”,其實也就是state字段,標明同時最多有state個線程可以獲取鎖(成功調用acquire()函數)
CyclicBarrier
1、解讀:
(1)內存屏障。設立一個目標,當所有線程都達到這個目標時,程序才能往下執行。
volatile
1、解讀:
(1)volatile修飾的變量對所有線程具有可見性。一個線程修改了這個變量的值,其他線程對于這個新值是可以立即得知的。原因如下:對于共享變量,當一個線程修改了這個變量,其他線程如果要讀取該變量,只能從主內存中讀取,而不能讀取工作內存中的變量,這樣就保證了線程讀取的變量都是最新的 (2)volatile修飾的變量禁止 指令重排序 的優化(普通變量不能保證變量賦值操作的順序與代碼中一樣,由于存在指令重排序優化,java代碼變成匯編代碼之后,代碼執行順序可能發生變化) (3)volatile無法保證原子性。 (4)除了volatile關鍵字,還有兩個關鍵字也能實現可見性。 A、 synchronize:“在對變量進行unlock操作之前,先把工作內存里面的值同步到主內存”,由這條規則獲得可見性。 B、 final:final修飾的字段一旦被初始化完成,其他線程中就能看到final字段的值
2、使用情況:
(1)某些情況下可以避免加鎖,提高程序并發性
ThreadLocal:
1、ThreadLocal用于實現線程之間數據獨立,從而避免數據共享,既然數據不共享了,自然就避免了線程安全問題,是同步的一種優化方案。
redis實現分布式鎖
1、解讀:
(1)Redis是單線程模型,單個命令操作是原子性的。 (2)NX指令: a、NX表示如果key不存在就添加,存在則直接返回 b、NX是實現分布式鎖的關鍵。 c、實例:SET key uuid NX PX timeout SET resource_name uniqueVal NX PX 30000
2、注意點:
(1)為了防止因為各種原因導致無法釋放鎖,所以會利用expire key second把key設置一個過期時間
(2)利用expire設置過期時間,還是可能存在問題。比如說在setnx key value和expire key second之間,發生了系統故障(或者其他原因),導致key沒有設置過期時間,還是可能發生死鎖。這時候,可以利用一條指令set lock:codehole true ex 5 nx,這條指令相當于先執行setnx再執行expire,同時保證原子性。
(3)在加鎖和釋放鎖時,需要保證是同一把鎖,通常的方法是使用uuid,存入key中,在釋放鎖時,把uuid和key中的值對比,相同則是同一把鎖。
為什么需要保證同一把鎖呢? 假設有A、B、C三臺機器,A先獲取鎖,假設A的業務執行時間比較長,鎖過期了(A的鎖被刪除了),這是B再請求并且獲取鎖,如果這時候A執行完了,不用判斷是否同一把鎖的情況下,A就刪除了B的鎖。這時候,如果C再請求獲取鎖,就出現B、C同時執行業務代碼的情況。
Zookeeper實現分布式鎖
1、參考:https://blog.csdn.net/sunfeiz...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19157.html
摘要:如問到是否使用某框架,實際是是問該框架的使用場景,有什么特點,和同類可框架對比一系列的問題。這兩個方向的區分點在于工作方向的側重點不同。 [TOC] 這是一份來自嗶哩嗶哩的Java面試Java面試 32個核心必考點完全解析(完) 課程預習 1.1 課程內容分為三個模塊 基礎模塊: 技術崗位與面試 計算機基礎 JVM原理 多線程 設計模式 數據結構與算法 應用模塊: 常用工具集 ...
摘要:目錄介紹問題匯總具體問題好消息博客筆記大匯總年月到至今,包括基礎及深入知識點,技術博客,學習筆記等等,還包括平時開發中遇到的匯總,當然也在工作之余收集了大量的面試題,長期更新維護并且修正,持續完善開源的文件是格式的同時也開源了生活博客,從年 目錄介紹 00.Java問題匯總 01.具體問題 好消息 博客筆記大匯總【16年3月到至今】,包括Java基礎及深入知識點,Android技...
摘要:的鎖是非公平鎖,默認情況下也是非公平鎖,但可以通過帶布爾值的構造函數要求使用公平鎖。有序性,是保證線程內串行語義,避免指令重排等。公平性是減少線程饑餓個別線程長期等待鎖,但始終無法獲取情況發生的一個辦法。 目錄介紹 1.Synchronize和ReentrantLock區別 1.1 相似點 1.2 區別 1.3 什么是線程安全問題?如何理解 1.4 線程安全需要保證幾個基本特性 ...
閱讀 3062·2021-10-12 10:12
閱讀 1569·2021-09-09 11:39
閱讀 1845·2019-08-30 15:44
閱讀 2339·2019-08-29 15:23
閱讀 2898·2019-08-29 15:18
閱讀 2960·2019-08-29 13:02
閱讀 2688·2019-08-26 18:36
閱讀 733·2019-08-26 12:08