導航:首頁 > 編程語言 > java鎖是什麼

java鎖是什麼

發布時間:2023-02-20 23:04:30

java多線程,對象鎖是什麼概念

java線程:

1.線程中一些基本術語和概念

1.1線程的幾個狀態
初始化狀態
就緒狀態
運行狀態
阻塞狀態
終止狀態
1.2 Daemon線程
Daemon線程區別一般線程之處是:主程序一旦結束,Daemon線程就會結束。
1.3鎖的定義
為了協調多個並發運行的線程使用共享資源才引入了鎖的概念。
1.4死鎖
任何多線程應用程序都有死鎖風險。當一組線程中的每一個都在等待一個只
有該組中另一個線程才能引起的事件時,我們就說這組線程死鎖了。換一個說法
就是一組線程中的每一個成員都在等待別的成員佔有的資源時候,就可以說這組
線程進入了死鎖。死鎖的最簡單情形是:線程 A 持有對象 X 的獨占鎖,並且
在等待對象 Y 的鎖,而線程 B 持有對象 Y 的獨占鎖,卻在等待對象 X 的鎖。
除非有某種方法來打破對鎖的等待(Java 鎖定不支持這種方法),否則死鎖的線
程將永遠等下去。

1.5.Java對象關於鎖的幾個方法
1.5.1 wait方法
wait方法是java根對象Object含有的方法,表示等待獲取某個鎖。在wait方法進入前,會釋放相應的鎖,在wait方法返回時,會再次獲得某個鎖。
如果wait()方法不帶有參數,那隻有當持有該對象鎖的其他線程調用了notify或者notifyAll方法,才有可能再次獲得該對象的鎖。
如果wait()方法帶有參數,比如:wait(10),那當持有該對象鎖的其他線程調用了notify或者notifyAll方法,或者指定時間已經過去了,才有可能再次獲得該對象的鎖。
參考 thread.lock.SleepAndWait
1.5.2 notify/notifyAll方法
這里我就不再說明了。哈哈,偷點懶。
1.5.3 yield方法
yield()會自動放棄CPU,有時比sleep更能提升性能。
1.6鎖對象(實例方法的鎖)
在同步代碼塊中使用鎖的時候,擔當鎖的對象可以是這個代碼所在對象本身或者一個單獨的對象擔任,但是一定要確保鎖對象不能為空。如果對一個null對象加鎖,會產生異常的。原則上不要選擇一個可能在鎖的作用域中會改變值的實例變數作為鎖對象。
鎖對象,一種是對象自己擔任,一種是定義一個普通的對象作為private property來擔任,另外一種是建立一個新的類,然後用該類的實例來擔任。
參考 :
thread.lock.UseSelfAsLock,使用對象自己做鎖對象
thread.lock.UseObjAsLock 使用一個實例對象作鎖對象
thread.lock.UseAFinalObjAsLock使用常量對象作為一個鎖對象
1.7類鎖
實例方法存在同步的問題,同樣,類方法也存在需要同步的情形。一般類方法的類鎖是一個static object來擔任的。當然也可以採用類本身的類對象來作為類鎖。
一個類的實例方法可以獲得該類實例鎖,還可以嘗試去訪問類方法,包含類同步方法,去獲得類鎖。
一個類的類方法,可以嘗試獲得類鎖,但是不可以嘗試直接獲得實例鎖。需要先生成一個實例,然後在申請獲得這個實例的實例鎖。
參考
thread.lock.UseStaticObjAsStaticLock 使用類的屬性對象作為類鎖。
thread.lock.UseClassAsStaticLock使用類的類對象作為類鎖

1.8.線程安全方法與線程不安全方法
如果一個對象的所有的public方法都是同步方法,也就是說是public方法是線程安全的,那該對象的private方法,在不考慮繼承的情況下,可以設置為不是線程安全的方法。
參考 thread.lock.SynMethrodAndNotSynMethrod

1.9類鎖和實例鎖混合使用
在實例方法中混合使用類鎖和實例鎖;可以根據前面說的那樣使用實例鎖和類鎖。
在類方法中混合使用類鎖和實例鎖,可以根據前面說的那樣使用類鎖,為了使用實例鎖,先得生成一個實例,然後實例鎖。
參考 thread.lock.StaticLockAndObjLock
1.10鎖的粒度問題。
為了解決對象鎖的粒度過粗,會導死鎖出現的可能性加大,鎖的粒度過細,會程序開發維護的工作加大。對於鎖的粒度大小,這完全要根據實際開發需要來考慮,很難有一個統一的標准。

1.11.讀寫鎖
一個讀寫鎖支持多個線程同時訪問一個對象,但是在同一時刻只有一個線程可以修改此對象,並且在訪問進行時不能修改。
有2種調度策略,一種是讀鎖優先,另外就是寫鎖優先。
參考 thread.lock.ReadWriteLock
1.12 volatile
在Java中設置變數值的操作,除了long和double類型的變數外都是原子操作,也就是說,對於變數值的簡單讀寫操作沒有必要進行同步。這在JVM 1.2之前,Java的內存模型實現總是從主存讀取變數,是不需要進行特別的注意的。而隨著JVM的成熟和優化,現在在多線程環境下volatile關鍵字的使用變得非常重要。在當前的Java內存模型下,線程可以把變數保存在本地內存(比如機器的寄存器)中,而不是直接在主存中進行讀寫。這就可能造成一個線程在主存中修改了一個變數的值,而另外一個線程還繼續使用它在寄存器中的變數值的拷貝,造成數據的不一致。要解決這個問題,只需要像在本程序中的這樣,把該變數聲明為volatile(不穩定的)即可,這就指示JVM,這個變數是不穩定的,每次使用它都到主存中進行讀取。一般說來,多任務環境下各任務間共享的標志都應該加volatile修飾。

2.線程之間的通訊
在其他語言中,線程之間可以通過消息隊列,共享內存,管道等方式來實現
線程之間的通訊,但是java中可以不採用這樣方式,關注的是線程之間的同步。
只要保證相關方法運行的線程安全,信息共享是自然就可以顯現了。
2.1屏障
屏障就是這樣的一個等待點: 一組線程在這一點被同步,這些線程合並各自的結果或者運行到整體任務的下一階段。
參考:
thread.lock. BarrierUseExample
thread.lock.Barrier
2.2.鎖工具類
提供對線程鎖的獲取,釋放功能。展示了鎖的獲取釋放過程。可以作為一個工具類來使用。
參考:thread.lock. BusyFlag

2.3.條件變數
條件變數是POSIX線程模型提供的一種同步類型,和java中的等待通知機制類似。
雖然java中已經有了等待通知機制,但是為了減少在notify/notifyAll方法中
線程調度的開銷,把一些不需要激活的線程屏蔽出去,引入了條件變數。
Java中2個(多個)條件變數可以是同一個互斥體(鎖對象)。
參考:thread.lock.CondVar 條件變數類
常見的應用情形:
一個鎖控制多個信號通道(例如:多個變數),雖然可以採用簡單java等待通知機制,但是線程調度效率不高,而且線程可讀性也不是太好,這時候可以採用創建一個鎖對象(BusyFlag實例),同時使用這個BusyFlag實例來創建多個條件變數(CondVar 實例)。
經常使用到CondVar類的地方是緩沖區管理,比如:管道操作之類的。先創建一個BusyFlag實例,然後創建CondVar 實例,用這個條件變數描述緩沖區是否為空,另外創建CondVar 實例作條件變數述緩沖區是否滿。
現實中,馬路的紅綠燈,就可以採用條件變數來描述。

3. Java線程調度
3.1 Java優先順序
java的優先順序別共有10種,加上虛擬機自己使用的優先順序別=0這種,總共11種。
大多數情況來說,java線程的優先順序設置越高(最高=10),那線程越優先運行。
3.2. 綠色線程
線程運行在虛擬機內,操作系統根本不知道這類線程的存在。
線程是由虛擬機調度的。
3.3 本地線程
線程是由運行虛擬機的操作系統完成的。
3.4 Windows本地線程
操作系統,完全能夠看得到虛擬機內的每一個線程,同時虛擬機的線程和操作系統的線程是一一對應的。Java的線程調度室由操作系統底層線程決定的。
在win32平台下,windows線程只有6個優先順序別。和java線程優先順序別對應如下:
Java線程優先順序 Windows 95/nt/2000線程優先順序
0 THREAD_ PRIORITY_IDLE
1(Thread.MIN_PRIORITY) THREAD_ PRIORITY_LOWEST
2 THREAD_ PRIORITY_LOWEST
3 THREAD_ PRIORITY_BELOW_NORMAL
4 THREAD_ PRIORITY_BELOW_NORMAL
5 (Thread.NORM_PRIORITY) THREAD_ PRIORITY _NORMAL
6 THREAD_ PRIORITY _ABOVE_NORMAL
7 THREAD_ PRIORITY _ABOVE_NORMA
8 THREAD_ PRIORITY _HIGHEST
9 THREAD_ PRIORITY _HIGHEST
10 (Thread.MAX_PRIORITY) THREAD_ PRIORITY _CRITICAL

3.5線程優先順序倒置與繼承
如果一個線程持有鎖(假設該線程名字=ThreadA,優先順序別=5),另外一個線程(假設該線程名字=ThreadB,優先順序別=7),現在該線程(ThreadA)處於運行狀態,但是線程ThreadB申請需要持有ThreadA所獲得的鎖,這時候,為了避免死鎖,線程A提高其運行的優先順序別(提高到ThreadB的優先順序別=7),而線程ThreadB為了等待獲得鎖,降低線程優先順序別(降低到ThreadA原來的優先順序別=5).
上述的這種情況,對於ThreadA,繼承了ThreadB的優先順序別,這成為優先順序別的繼承;對於ThreadB暫時降低了優先順序別,成為優先順序別的倒置。
當然,一旦線程ThreadA持有的鎖釋放了,其優先順序別也會回到原來的優先順序別(優先順序別=5)。線程ThreadB獲得了相應的鎖,那優先順序別也會恢復到與原來的值(優先順序別=7)。

3.6循環調度
具有同樣優先順序的線程相互搶占成為循環調度。

4.線程池
創建一個線程也是需要一定代價的,為了降低這個代價,採用了和普通對象池的思想建立線程池,以供系統使用。
線程消耗包括內存和其它系統資源在內的大量資源。除了 Thread 對象所需的內存之外,每個線程都需要兩個可能很大的執行調用堆棧。除此以外,JVM 可能會為每個 Java 線程創建一個本機線程,這些本機線程將消耗額外的系統資源。最後,雖然線程之間切換的調度開銷很小,但如果有很多線程,環境切換也可能嚴重地影響程序的性能。
使用線程池的方式是,先建立對象池,然後申請使用線程,程序線程運行,運行完畢,把線程返回線程池。
使用線程池的風險:同步錯誤和死鎖,與池有關的死鎖、資源不足和線程泄漏。
大家有空可以研究一下tomcat的線程池實現原理思想。
實際上是tomcat已經在從線程池的使用線程時候加上了事件處理機制。
個人認為,線程池之類的實現,一般不要自己實現,因為自己實現主要是穩定性等方面可能作的不夠好。
可以參考 apache的jakarta-tomcat-5.5.6的相關代碼,具體是:
jakarta-tomcat-connectors\util\java\org\apache\tomcat\util\threads的相關代碼

5工作隊列
使用工作隊列的好處是不象直接使用線程池那樣,當線城池中沒有線程可以使用的時
候,使用者需要處於等待狀態,不能進行其他任務的處理。
工作隊列的工作原理是:
採用後台線程處理方式,客戶端把任務提交給工作隊列,工作隊列有一組內部可以工作線程,這些工作線程從工作隊列中取出任務運行,一個任務完成後,就從隊列獲取下一個任務進行處理。當工作隊列中沒有任務可以處理時候,工作線程就處於等待狀態,直到獲得新的任務時候,才進行新的處理。

Ⅱ Java中有哪些鎖,區別是什麼

【1】公平所和非公平所。
公平鎖:是指按照申請鎖的順序來獲取鎖,
非公平所:線程獲取鎖的順序不一定按照申請鎖的順序來的。

//默認是不公平鎖,傳入true為公平鎖,否則為非公平鎖
ReentrantLock reentrantLock = new ReetrantLock();
1
2
【2】共享鎖和獨享鎖
獨享鎖:一次只能被一個線程所訪問
共享鎖:線程可以被多個線程所持有。
ReadWriteLock 讀鎖是共享鎖,寫鎖是獨享鎖。
【3】樂觀鎖和悲觀鎖。
樂觀鎖:對於一個數據的操作並發,是不會發生修改的。在更新數據的時候,會嘗試採用更新,不斷重入的方式,更新數據。
悲觀鎖:對於同一個數據的並發操作,是一定會發生修改的。因此對於同一個數據的並發操作,悲觀鎖採用加鎖的形式。悲觀鎖認為,不加鎖的操作一定會出問題,
【4】分段鎖
1.7及之前的concurrenthashmap。並發操作就是分段鎖,其思想就是讓鎖的粒度變小。
【5】偏向鎖是指一段同步代碼一直被一個線程所訪問,那麼該線程會自動獲取鎖。降低獲取鎖的代價
輕量級鎖
重量級鎖
【6】自旋鎖
自旋鎖

Ⅲ JAVA中的內鎖機制是什麼

多線程同步的實現最終依賴鎖機制。我們可以想像某一共享資源是一間屋子,每個人都是一個線程。當A希望進入房間時,他必須獲得門鎖,一旦A獲得門鎖,他進去後就立刻將門鎖上,於是B,C,D...就不得不在門外等待,直到A釋放鎖出來後,B,C,D...中的某一人搶到了該鎖(具體搶法依賴於JVM的實現,可以先到先得,也可以隨機挑選),然後進屋又將門鎖上。這樣,任一時刻最多有一人在屋內(使用共享資源)。 Java語言規范內置了對多線程的支持。對於Java程序來說,每一個對象實例都有一把「鎖」,一旦某個線程獲得了該鎖,別的線程如果希望獲得該鎖,只能等待這個線程釋放鎖之後。獲得鎖的方法只有一個,就是synchronized關鍵字。

Ⅳ 在java中有哪些鎖

給你整理了Java中的一些鎖:

Ⅳ JAVA的瑣是什麼有幾種鎖幾種鎖的區別又是什麼

眾所周知,java開發語言提供了很方便的開發平台,而且開發出來的程序很容易在不同的平台上面進行移植,現在越來越多的人使用它開發軟體。
Java有了它方便的一個方面,但是他同時也帶給了開發者一個煩惱,這就是保護的辦法不多,而且大多數不是很好用,這樣自己辛苦開發出來的程序很容易被人復制而據為己有,一般情況下,大多數的人都是用混編器(java obfuscator)來把開發出來的程序進行打亂以達到沒有辦法來反編譯觀看源代碼,但是這種辦法在網上很容易找到相關的軟體來重新整理,那麼這個混編只能控制一些本來也沒有辦法動您的軟體的人,而對於一些掌握工具的人幾乎是透明的,還有就是利用硬體加密鎖,但大多數公司提供的硬體加密鎖只是提供了一些dll的連接或簡單的api調用,只要反編譯他們,就很容易把一些api調用去掉,這樣硬體加密鎖也就不起作用了,但是現在到底有沒有好的辦法呢?
以色列阿拉丁公司提供的*** HL加密鎖提供的外殼加密工具中有一個叫做數據加密的功能,這個功能能更好的防止去除api的調用,各位都知道:硬體加密鎖的保護原理就是要您被加密過的軟體和加密鎖的硬體要緊緊地結合在一起,而且不容易被輕易的剔出原來的調用,這樣才能更好的保證您的軟體不被盜版,同時這種方式也很容易被程序員掌握,要對一個軟體實現保護,只需要幾分鍾的時間就可以了,下面簡單介紹一下他的原理:
運用阿拉丁公司提供的外殼工具先把調用您的java解釋器來進行加密,那麼就是說如果要運用這個解釋器就需要有一把特定的加密鎖存在,然後我們再運用它提供的外殼加密工具中的內容加密,把您寫好的java程序當作一個文件來處理而對他進行加密,這個加密是採用的AES128位的演算法的,這樣這個加密過的數據文件??您的軟體就只能被您保護過的java解釋器來進行解釋,但是在沒有加密鎖的情況下就不能夠運行您的軟體,從而達到真正保護您的軟體的目的。

閱讀全文

與java鎖是什麼相關的資料

熱點內容
伺服器如何搭建類似github 瀏覽:288
明日之後安卓太卡怎麼辦 瀏覽:502
如何使用命令方塊找到村莊 瀏覽:766
泛函壓縮映像原理 瀏覽:521
win10清除文件夾瀏覽記錄 瀏覽:964
如何查看伺服器域中所有服務 瀏覽:384
學mastercam91編程要多久 瀏覽:999
如何查伺服器地址和埠 瀏覽:911
教學雲平台app怎麼下載 瀏覽:389
單片機510教學視頻 瀏覽:624
陝西信合app怎麼查看自己的存款 瀏覽:663
風冷冰箱有壓縮機 瀏覽:274
android實現wifi連接wifi 瀏覽:669
飛豬app怎麼幫別人值機 瀏覽:924
筆記本開我的世界伺服器地址 瀏覽:546
怎樣隱藏bat命令 瀏覽:127
android開發創意 瀏覽:138
京劇貓為什麼進不去伺服器 瀏覽:784
怎麼自己免費製作一個手機app 瀏覽:582
python同時迭代兩個變數 瀏覽:741