您好,登錄后才能下訂單哦!
本篇內容主要講解“Java多線程的實現原理及案例”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java多線程的實現原理及案例”吧!
信號量的四要素為:最大許可數、公平模式、acquire方法以及release方法。最大許可數和公平模式在構建Semaphore對象時指定,分別表示公共資源最多可以多少個線程同時訪問以及獲取許可時是否使用公平模式。acquire方法用于獲取許可,假如因為不足許可的話則進入等待狀態。release方法用于釋放許可。
Semaphore類的實現是基于AQS同步器來實現的,不管是公平模式還是非公平模式都是基于AQS的共享模式,只是在獲取許可的操作邏輯有差異。Semaphore的默認模式為非公平模式,我們先看非公平模式的實現。?
Semaphore類的幾個主要方法如下所示,其中提供了兩個構造函數,相關的兩個參數為許可最大數和是否使用公平模式,其中FairSync是公平模式的同步器而NonfairSync則是非公平模式的同步器。有兩個acquire方法,無參時默認是一次獲取1個許可,而如果傳入整型參數則表示一次獲取若干個許可。對應地,也有兩個release方法,無參時表示釋放1個許可,而整型參數則表示一次釋放若干個許可。Semaphore主要的幾個方法如下
Semaphore內部的Syn子類是公平模式FairSync類和非公平模式NonfairSync類的抽象父類,許可最大數與AQS同步器的狀態變量對應。因為模式是非公平模式,所以這里提供了非公平的許可獲取方法nonfairTryAcquireShared。非公平模式其實就是在許可數量允許的情況下,讓所有線程都進行自旋操作,而不管它們先來后到的順序,全部線程放到一起去競爭許可。其中compareAndSetState方法提供了CAS算法從而能夠保證并發修改許可值,而剩余許可數等于當前可用許可值減去當前消耗許可數,需要注意的是當剩余許可數小于0時則返回負數從而導致線程會進入等待隊列中。tryReleaseShared方法則提供了釋放許可的操作,不管是不是公平模式都使用該方法即可,釋放許可的邏輯是相同的。通過自旋操作來將釋放的許可數增加到當前剩余許可數。
非公平模式NonfairSync類的實現主要是tryAcquireShared方法,直接調用父類Sync的的nonfairTryAcquireShared方法即可。?
?
公平模式與非公平模式的主要差異就在獲取許可時的機制,非公平模式直接通過自旋操作讓所有線程競爭許可,從而導致了非公平。而公平模式則通過隊列來實現公平機制。它們的差異就在tryAcquireShared方法,我們看公平模式的tryAcquireShared方法。實際上不同的地方就在下圖中加了方框的兩行代碼,它會檢查是否已經存在等待隊列,如果已經有等待隊列則返回-1,返回-1則表示讓AQS同步器將當前線程進入等待隊列中,隊列則意味著公平。實際上,這也并非是嚴格的公平,在前面講到的AQS同步器的公平性章節有深入講過AQS的公平性,如果忘記了可以重新查閱加深理解。而且在為達到最大許可數的情況下,所有線程也并沒有進入等待隊列中,而是全部線程進行自旋獲取許可。
我們先看一個簡單的例子,首先實例化一個擁有5個許可的信號量對象,然后一共有10個線程一同嘗試獲取5個許可,得到許可的線程將value進行累加1,接著睡眠五秒,最后釋放許可。
以上程序輸出如下,其中有五個線程輸出“counting number : xx”后其他線程則開始等待。大概等待5秒后獲得許可的五個線程執行釋放許可操作,然后其它線程才能獲得許可并往下執行。
例子二與例子一很相似,不同的地方在于每次獲取許可時會消耗2個許可,同樣釋放時也釋放2個許可。這里實例化一個擁有6個許可的信號量對象,然后10個線程一同嘗試獲取許可。但這次最多只能同時3個線程得到許可,也就是三個線程得到許可后對value值進行累加1,然后睡眠5秒后釋放許可。接著另外三個線程又獲得許可往下執行,直到10個線程都執行完。
到此,相信大家對“Java多線程的實現原理及案例”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。