如何喚醒一個阻塞的線程?
這個問題需要分情況來分析,首先我們來看看導致線程阻塞的幾種情況:
通過調用sleep使任務進入休眠狀態
通過調用wait使線程掛起
等待IO
等待可用的鎖
接下來我們單獨分析這幾種阻塞的情況:
對於調用sleep導致的阻塞,可以使用Thread.interrupt喚醒。
調用wait的方法導致線程阻塞的,也可以使用Thread.interrupt進行喚醒。同時也可以調用notify/notifyAll進行喚醒,其中notify只會喚醒一個線程,需要持有相同object的線程進行競爭。調用notifyAll會喚醒所有持有相同object的線程。
如果是由於等待IO導致的阻塞,通過java直接喚醒是比較困難的,這個時候就需要從外部資源入手,比如直接關閉對應資源的IO。
synchronized是無法直接被中斷的,ReentrantLock則可以被中斷。
多線程死鎖
Java中的volatile關鍵字有什麼作用?如何使用?它和synchronized有什麼區別?
如果一個字段被聲明或volatile,java線程內存模型確保所有線程看到這個變量值是一致的。volatile變量修飾符如果使用恰當的話,它比synchronized的使用和執行成本會更低,因為它不會引起線程上下文的切換和調度。
synchronized與volatile實現同步的區別:
synchronized是一個重量級的同步功能,會切換上下文。volatile是一個輕量級的同步功能,無需進行上下文的切換。
synchronized需要在不同線程中爭搶同一個鎖,會出現死鎖的情況,而volatile則不需要進行爭搶,也不會出現死鎖的情況。
Java中的wait和sleep這兩個方法有什麼區別?
sleep方法是使線程停止一段時間的方法。在sleep 時間間隔期滿後,線程不一定立即恢復執行。這是因為在那個時刻,其它線程可能正在運行而且沒有被調度為放棄執行,除非“醒來”的線程具有更高的優先級。
wait是線程交互時,如果線程對一個同步對象x 發出一個wait()調用,該線程會暫停執行,被調對象進入等待狀態,直到被喚醒或等待時間到。
sleep是Thread中的方法,而wait是Object的方法。sleep不會釋放所持有的鎖,而wait會釋放所持有的鎖。
給你3個線程T1、T2和T3。如何保證T1執行後開始執行T2,T2執行以後開始執行T3?
如果知道join這個方法的功能,那麼這個問題就沒有任何難度了。這個面試題比較簡單,面試官一般會在最開始的時候用這個問題來試探一下被面試者是否對多線程有所瞭解。
什麼是原子操作?
所謂原子操作是指不會被線程調度機制打斷的操作;這種操作一旦開始,就一直運行到結束,中間不會有任何線程切換。
閱讀更多 java小碼農 的文章