Java進階(7) - 併發(多線程基本概念)

1、中斷
interrupt方法只改變目標線程的中斷狀態(interrupt status),當線程處於 wait、sleep、join等狀態時
都在方法內部不斷地檢查中斷狀態的值,當調用interrupt會拋出InterruptedException異常。java

interrupt方法
Thread實例方法: 必須由其它線程獲取被調用線程的實例後,進行調用。實際上,只是改變了被調用線程的內部中斷狀態;segmentfault

Thread.interrupted方法
Thread類方法: 必須在當前執行線程內調用,該方法返回當前線程的內部中斷狀態,而後清除中斷狀態(置爲false) 安全

isInterrupted方法
Thread實例方法:用來檢查指定線程的中斷狀態。當線程爲中斷狀態時,會返回true;不然返回false。ide

2、協調
wait set / wait方法
每一個Java類的實例都有一個wait set,當對象執行wait方法時,當前線程就會暫停,並進入該對象的wait set
注: 當前線程若要執行obj.wait(),則必須先獲取該對象鎖。當線程進入wait set後,就已經釋放了該對象鎖。性能

notify方法
notify方法至關於從wait set中從挑出一個線程並喚醒。
下圖中線程A在當前實例對象的wait set中等待,此時線程B必須拿到同一實例的對象鎖,才能調用notify方法喚醒wait set中的任意一個線程。線程

notifyAll方法
notifyAll方法至關於將wait set中的全部線程都喚醒。對象

wait、notify、notifyAll這三個方法都是java.lang.Object類的方法(注意,不是Thread類的方法)。
若線程沒有拿到當前對象鎖就直接調用對象的這些方法,都會拋出java.lang.IllegalMonitorStateException異常。blog

  • obj.wait()是把當前線程放到obj的wait set;
  • obj.notify()是從obj的wait set裏喚醒1個線程;
  • obj.notifyAll()是喚醒全部在obj的wait set裏的線程。

3、線程的狀態轉移接口

  • 當建立一個Thread子類或實現Runnable接口類的實例時,線程進入【初始】狀態;
  • 調用實例的start方法後,線程進入【可執行】狀態;
  • 系統會在某一時刻自動調度處於【可執行】狀態的線程,被調度的線程會調用run方法,進入【執行中】狀態;
  • 線程執行完run方法後,進入【結束】狀態;
  • 處於【結束】狀態的線程,在某一時刻,會被JVM垃圾回收;
  • 處於【執行中】狀態的線程,若調用了Thread.yield方法,會回到【可執行】狀態,等待再次被調度;
  • 處於【執行中】狀態的線程,若調用了wait方法,會進入wait set並一直等待,直到被其它線程經過notify、notifyAll、interrupt方法喚醒;
  • 處於【執行中】狀態的線程,若調用了Thread.sleep方法,會進入【Sleep】狀態,沒法繼續向下執行。當sleep時間結束或被interrupt時,會回到【可執行狀態】;
  • 處於【執行中】狀態的線程,若遇到阻塞I/O操做,也會中止等待I/O完成,而後回到【可執行狀態】

4、不可變模式
Immutable(不變的)參與者
Immutable參與者是一個字段值沒法更改的類,也沒有任何用來更改字段值的方法。當Immutable參與者的實例創建後,狀態就徹底再也不變化。get

適用場景:
Immutable模式的優勢在於,「不須要使用synchronized保護」。而「不須要使用synchronized保護」的最大優勢就是可在不喪失安全性與生命性的前提下,提升程序的執行性能。若例由多數線程所共享實,且訪問很是頻繁,Immutable模式就能發揮極大的優勢。(final修飾變量性能高的緣由之一)

參考:https://segmentfault.com/blog/ressmix_multithread?page=3

相關文章
相關標籤/搜索