LockSupport的用法及原理

介紹:

LockSupport是一個線程阻塞工具類,所有的方法都是靜態方法,可以讓線程在任意位置阻塞,當然阻塞之後肯定得有喚醒的方法。

 

LockSupport 提供park()和unpark()方法實現阻塞線程和解除線程阻塞,LockSupport和每個使用它的線程都與一個許可(permit)關聯。permit相當於1,0的開關,默認是0,調用一次unpark就加1變成1,調用一次park會消費permit, 也就是將1變成0,同時park立即返回。再次調用park會變成block(因爲permit爲0了,會阻塞在這裏,直到permit變爲1), 這時調用unpark會把permit置爲1。每個線程都有一個相關的permit, permit最多隻有一個,重複調用unpark也不會積累。

 

這兒parkunpark其實實現了waitnotify的功能,不過還是有一些差別的。

  1. park不需要獲取某個對象的鎖
  2. 因爲中斷的時候park不會拋出InterruptedException異常,所以需要在park之後自行判斷中斷狀態,然後做額外的處理

還有一個地方需要注意,相對於線程的stop和resumepark和unpark的先後順序並不是那麼嚴格。stop和resume如果順序反了,會出現死鎖現象,所以

park()和unpark()不會有 Thread.suspendThread.resume 所可能引發的死鎖問題,由於許可的存在,調用 park 的線程和另一個試圖將其 unpark 的線程之間的競爭將保持活性

LockSupport.park()和unpark()和object.wait()和notify()很相似,那麼它們有什麼區別呢?

  1. 面向的主體不一樣。LockSuport主要是針對Thread進進行阻塞處理,可以指定阻塞隊列的目標對象,每次可以指定具體的線程喚醒。Object.wait()是以對象爲緯度,阻塞當前的線程和喚醒單個(隨機)或者所有線程。
  2. 實現機制不同。雖然LockSuport可以指定monitor的object對象,但和object.wait(),兩者的阻塞隊列並不交叉。可以看下測試例子。object.notifyAll()不能喚醒LockSupport的阻塞Thread.

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章