https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247485352&idx=1&sn=175dfedebb2515c075a2f761279ab4ce&chksm=ebd63884dca1b1920b652dae20cda1f2dbcfef00c11671011a0f1587e05e3784a88a38055d91&mpshare=1&scene=1&srcid=0514yZSBFo8l622hi0TJmRic&key=1ffebf935a11638d3eac99db4837924505ff844acd775a7daa06f8239c722818a59a5624f6f1936639df8d47cac8a738b71c2913eee9878c6b0360dfabd0ba92b0f9c8b57c1f53032ed564d2c2f6ca98&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=vzUL0Wl%2BAmaDy8sElICVNpoR9K1k%2BTNUs6WnJljlwO%2FA7ylxk%2BcnB%2BzeNyLoUWiI
總結一下:
1.
線程創建之后調用start()方法開始運行,當調用wait(),join(),LockSupport.lock()方法線程會進入到WAITING狀態,而同樣的wait(long timeout),sleep(long),join(long),LockSupport.parkNanos(),LockSupport.parkUtil()增加了超時等待的功能,也就是調用這些方法后線程會進入TIMED_WAITING狀態,當超時等待時間到達后,線程會切換到Runable的狀態,另外當WAITING和TIMED _WAITING狀態時可以通過Object.notify(),Object.notifyAll()方法使線程轉換到Runable狀態。
當線程出現資源競爭時,即等待獲取鎖的時候,線程會進入到BLOCKED阻塞狀態,當線程獲取鎖時,線程進入到Runable狀態。線程運行結束后,線程進入到TERMINATED狀態,
響應中斷:
操作|狀態|方式
no | Runnable | while 循環+isInterrupted
synchoronize | blocked | 無法響應
lock/lockInterruptely | blocked | InterruptedException
wait await | waiting/timed waiting | InterruptedException
2.
中斷可以理解為線程的一個標志位,它表示了一個運行中的線程是否被其他線程進行了中斷操作。中斷好比其他線程對該線程打了一個招呼。其他線程可以調用該線程的interrupt()方法對其進行中斷操作,同時該線程可以調用 isInterrupted()來感知其他線程對其自身的中斷操作,從而做出響應。
另外,同樣可以調用Thread的靜態方法 interrupted()對當前線程進行中斷操作,該方法會清除中斷標志位。需要注意的是,當拋出InterruptedException時候,會清除中斷標志位,也就是說在調用isInterrupted會返回false。
一旦拋出InterruptedException,isInterrupted返回false
interrupted是靜態方法,返回的是當前線程的中斷狀態。例如,如果當前線程被中斷(沒有拋出中斷異常,否則中斷狀態就會被清除),你調用interrupted方法,第一次會返回true。然后,當前線程的中斷狀態被方法內部清除了。第二次調用時就會返回false。https://www.cnblogs.com/w-wfy/p/6414801.html
書上有個例子
對於isInterrupted(),如果之前調用過thread.interrupt()
,那么它的返回值是true。它的作用就是返回該線程是否有中斷標志。多次調用這個方法的結果是一樣的。
3.
守護線程在退出的時候並不會執行finnaly塊中的代碼,所以將釋放資源等操作不要放在finnaly塊中執行,這種操作是不安全的。
線程可以通過setDaemon(true)的方法將線程設置為守護線程。並且需要注意的是設置守護線程要先於start()方法,否則會報:
Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.setDaemon(Thread.java:1365) at learn.DaemonDemo.main(DaemonDemo.java:19)
這樣的異常,但是該線程還是會執行,只不過會當做正常的用戶線程執行。