1. 程式人生 > >java執行緒相關知識點整理

java執行緒相關知識點整理

1、建立新執行緒例項:
Extends Thread類並重寫run方法,建立這個類的例項即可;
或者建立一個類,實現Runnable介面,實現run方法,通過將這個類的例項傳入Thread的構造器來建立一個Thread例項,這例項呼叫start方法時,這個實現類實現的run方法會在這個單獨執行中的執行緒種被自動呼叫。
兩種方法的比較:實現runnable介面更適合於if you are only planning to override the run() method and no other Thread methods.

2、Runnable介面:
The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. 這些類必須實現該介面的無引數run方法。這個介面也只有這一個方法。
In most cases, the Runnable interface should be used

3、執行緒池ThreadPoolExecutor
1)就是一個複用執行緒的機制,採用一個由實現了runnable介面的類例項作為元素的佇列,多個執行緒迴圈從佇列中取出任務並呼叫其run方法執行,這樣就實現了對執行緒的複用。它實現了interrupt方法可以中斷當前全部執行緒

2)使用執行緒池的好處:
減少在建立和銷燬執行緒上所花的時間以及系統資源的開銷
如果不使用執行緒池,有可能造成系統建立大量執行緒而導致消耗完系統記憶體以及”過度切換”。

3)java提供的執行緒池的種類:
提供了幾種不同的構造器,通過限制一些引數來表現特定執行緒池的一些特點。
a、newFixedThreadPool 佇列長度沒有限制
建立一個指定工作執行緒數量的執行緒池。每當提交一個任務就建立一個工作執行緒,如果工作執行緒數量達到執行緒池初始的最大數,則將提交的任務存入到池佇列中。

b、newCachedThreadPool 執行緒數量沒有限制

建立一個可快取的執行緒池。這種型別的執行緒池特點是:
1).工作執行緒的建立數量幾乎沒有限制(其實也有限制的,數目為Interger. MAX_VALUE), 這樣可靈活的往執行緒池中新增執行緒。
2).如果長時間沒有往執行緒池中提交任務,即如果工作執行緒空閒了指定的時間(預設為1分鐘),則該工作執行緒將自動終止。終止後,如果你又提交了新的任務,則執行緒池重新建立一個工作執行緒。

c、newSingleThreadExecutor建立一個單執行緒化的Executor,即只建立唯一的工作者執行緒來執行任務,如果這個執行緒異常結束,會有另一個取代它,保證順序執行(我覺得這點是它的特色)。單工作執行緒最大的特點是可保證順序地執行各個任務,並且在任意給定的時間不會有多個執行緒是活動的 。

總結:FixedThreadPool是一個典型且優秀的執行緒池,它具有執行緒池提高程式效率和節省建立執行緒時所耗的開銷的優點。但是,線上程池空閒時,即執行緒池中沒有可執行任務時,它不會釋放工作執行緒,還會佔用一定的系統資源。 
CachedThreadPool的特點就是線上程池空閒時,即執行緒池中沒有可執行任務時,它會釋放工作執行緒,從而釋放工作執行緒所佔用的資源。但是,但當出現新任務時,又要建立一新的工作執行緒,又要一定的系統開銷。並且,在使用CachedThreadPool時,一定要注意控制任務的數量,否則,由於大量執行緒同時執行,很有會造成系統癱瘓。 

4)其他:
執行緒池可巢狀,樹形
執行緒池與執行緒池之間是相互隔離的,不可訪問父執行緒池的資訊不可訪問其他執行緒池的資訊

4、sychronize關鍵字和volitale關鍵字,happens before原則
Happens-before 關係
happens-before 關係保證:如果執行緒 A 與執行緒 B 滿足 happens-before 關係,則執行緒 A 執行動作的結果對於執行緒 B 是可見的。如果兩個操作未按 happens-before 排序,JVM 將可以對他們任意重排序。
下面介紹幾個與理解 ConcurrentHashMap 有關的 happens-before 關係法則:
* 程式次序法則:如果在程式中,所有動作 A 出現在動作 B 之前,則執行緒中的每動作 A 都 happens-before 於該執行緒中的每一個動作 B。
* 監視器鎖法則:對一個監視器的解鎖 happens-before 於每個後續對同一監視器的加鎖。先釋放再獲取。
* Volatile 變數法則:對 Volatile 域的寫入操作 happens-before 於每個後續對同一 Volatile 的讀操作。
* 傳遞性:如果 A happens-before 於 B,且 B happens-before C,則 A happens-before C。

5、執行緒安全的容器類
copyOnwriteArrayList 採用copy on write機制,寫時存在兩個副本
Vector
ConcorrentHashMap還沒看

6、Object的wait() notify()方法 Thread的sleep方法
(1)sleep 是執行緒類(Thread)的方法,導致此執行緒暫停執行指定時間,給執行機會給其他執行緒,但是監控狀態依然保持,到時後會自動恢復。呼叫sleep 不會釋放物件鎖。
(2)wait 是Object 類的方法,對此物件呼叫wait 方法導致本執行緒放棄物件鎖,進入等待此物件的等待鎖定池,只有針對此物件發出notify 方法(或notifyAll)後本執行緒才進入物件鎖定池準備獲得物件鎖進入執行狀態。
(3)wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用(使用範圍)

7、sychronized與reentrantlock:
後者叫可重入鎖,但其實兩者都是同一個執行緒可重入的,都是同一個執行緒每進入一次,鎖的計數器都自增1,所以要等到鎖的計數器下降為0時才能釋放鎖
前者是基於jvm實現的,後者是jdk實現的

(1)便利性:很明顯Synchronized的使用比較方便簡潔,並且由編譯器去保證鎖的加鎖和釋放,而ReenTrantLock需要手工宣告來加鎖和釋放鎖,為了避免忘記手工釋放鎖造成死鎖,所以最好在finally中宣告釋放鎖。
(2)粒度和靈活度:synchronized方法級,ReenTrantLock優於Synchronized
(3)reentrantlock是在sychronized基礎上提供更多功能:

1、公平非公平 ReenTrantLock可以指定是公平鎖還是非公平鎖。而synchronized只能是非公平鎖。所謂的公平鎖就是先等待的執行緒先獲得鎖。
2、condition 分類喚醒該類全部。ReenTrantLock提供了一個Condition(條件)類,用來實現分組喚醒需要喚醒的執行緒們,而不是像synchronized要麼隨機喚醒一個執行緒要麼喚醒全部執行緒。
 3、支援interupt。ReenTrantLock提供了一種能夠中斷等待鎖的執行緒的機制,通過lock.lockInterruptibly()來實現這個機制。

Reentrantlock原理:實現是一種自旋鎖,通過迴圈呼叫CAS操作來實現加鎖,可以避免使執行緒進入核心臺的阻塞狀態

scheduler