1. 程式人生 > >多執行緒學習筆記

多執行緒學習筆記

一、執行緒

1、定義執行緒有兩種方式:擴充套件Thread類和實現Runnable介面。使用start方法啟動執行緒。

2、執行緒狀態:建立(new),就緒(Runnable),執行(Running),阻塞(Blocked)和終止(dead),狀態轉換如下圖。

3、sleep和wait的區別

 1)sleep是Thread類的方法,wait是Object類的方法  2)Thread.sleep不會導致鎖行為的改變, 如果當前執行緒是擁有鎖的, 那麼Thread.sleep不會讓執行緒釋放鎖  3)Thread.sleep和Object.wait都會暫停當前的執行緒. OS會將執行時間分配給其它執行緒. 區別是, 呼叫wait後, 需要別的執行緒執行notify/notifyAll才能夠重新獲得CPU執行時間。

4、sleep和yield方法區別  1) sleep方法給其他執行緒執行機會時不會考慮執行緒的優先順序,因此低優先順序的執行緒也有機會執行。yield方法只會給相同優先順序或更高優先順序的執行緒以執行的機會   2)執行緒執行sleep方法後轉入阻塞狀態,而yield方法執行後轉入就緒(ready)狀態   3)sleep方法宣告丟擲InterruptException,而yield方法沒有宣告任何異常   4)  sleep方法比yield方法具有更好的移植性

5、常用方法

start(): 使執行緒開始執行;java虛擬機器呼叫該執行緒的run方法 run():執行業務方法 setName():改變執行緒名稱,使之與引數name相同 setPriority():更改執行緒的優先順序 setDaemon(boolean):將改執行緒標記為守護執行緒或使用者執行緒;守護執行緒是在後臺執行並且不會阻止JVM終止的執行緒,當沒有使用者執行緒在執行的時候,JVM關閉程式並且退出。 join(long milliesec):等待執行緒終止的時間最長為millis毫秒,當前執行緒A等待thread執行緒終止之後才從thread.join()返回。 interrupt():中斷執行緒 isAlive():測試執行緒是否處於活動狀態 yield():暫停當前正在執行的執行緒物件,並執行其他執行緒,放棄時間不確定,不會讓出鎖 sleep():指定的毫秒內讓正在執行的執行緒休眠 currentThread():返回對當前正在執行的執行緒物件的引用

6、並行:多個cpu例項或者多臺機器同時執行一段處理邏輯,是真正的同時。

     併發:通過cpu排程演算法,讓使用者看上去是同步執行。        悲觀鎖         synchronized:假定會發生併發衝突,遮蔽一切可能違反資料完整性的操作        樂觀鎖:假設不會發生併發衝突,只在提交操作時檢查是否違反資料完整性。如CAS atomic;缺點是不能解決髒讀問題,會出現ABA問題,新增版本號來避免此問題

二、執行緒間通訊方式

1、管道:半雙工,資料只能單向流動,有血緣關係的程序間流動

2、有名管道: 允許無血緣關係的程序間流動

3、訊號量:訊號量是一個計數器,可以用來控制多個程序對共享資源的訪問。是一種同步手段

4、訊息佇列:由訊息組成的連結串列,存放在核心中,並由訊息佇列識別符號標識

5、訊號: 用於通知接收程序某一事件已經發生。

6、共享記憶體

7、套接字socket     長連線:整個通訊過程,客戶端和服務端只用一個Socket物件,長期保持Socket的連線     短連線:每次請求,都新建一個Socket,處理完一個請求就直接關閉掉Socket

三、執行緒間通訊機制

有鎖機制、訊號量機制和訊號機制

鎖機制:     互斥鎖: 提供了以排它方式阻止資料結構被併發修改的方法     讀寫鎖:允許多個執行緒同時讀共享資料,而對寫操作互斥     條件變數:可以以原子阻塞程序,直到某個特定條件為真為止

訊號量機制:包括無名執行緒訊號量與有名執行緒訊號量

四、執行緒安全的實現方法

1、互斥同步:臨界區、互斥量、訊號量

2、非阻塞同步: 硬體指令集

3、ReentrantLock:可重入鎖     1)等待可中斷:持有鎖的執行緒長期不釋放鎖的時候,正在等待的執行緒可以選擇放棄等待,改為處理其他事情     2)可實現公平鎖:公平鎖是指多個執行緒在等待同一個鎖時,必須按照申請鎖的時間順序來依次獲得鎖;     3)鎖可以繫結多個條件     4)預設非公平的通過帶布林值的建構函式要求使用公平鎖

4、synchronized     重量級操作,狀態切換需要耗費很多的處理器時間。確實必要才使用,虛擬機器本身對它的優化:通知作業系統阻塞執行緒之前加入一段自旋等待過程,避免頻繁的切入到核心狀態之中。是非公平的。

5、如何確保執行緒安全

1)使用原子類 2)實現併發鎖 3)使用volitale關鍵字 4)使用不變類和執行緒安全類

五、Web併發訪問問題

1、Servlet執行緒安全問題:單例模式,存線上程安全問題        1)在Servlet中不要定義類變數或例項變數        2)為操作該變數的所有方法加synchronized修飾符,進行同步控制

2、Spring執行緒安全問題:優點是我們不用每次建立Controller, 減少了物件建立和垃圾收集的時間,缺點是併發訪問時會出現安全問題。     1)避免在Controller中定義類變數和例項變數     2)在Controller中使用ThreadLocal變數     3)宣告scope="prototype",每次建立新的Controller

3、SpringMVC執行緒安全問題     1)對操作共享變數的所有方法進行同步控制     2)同步共享變數如:Collections.synchronizedMap()     3)使用同步物件

六、執行緒池     1、為什麼使用執行緒池         1)建立/銷燬執行緒伴隨著系統開銷,過於頻繁,影響處理效率         2)執行緒併發數量過多,搶佔系統資源導致阻塞         3)對執行緒進行一些簡單的管理(延時,定時迴圈等)     2、優點         1)降低資源消耗         2)提高響應速度         3)提高執行緒的可管理性     3、java.uitl.concurrent.ThreadPoolExecutor         1)corePoolSize:核心執行緒數最大值         2)maximunPoolSize:執行緒池最大執行緒數(核心執行緒 + 非核心執行緒)         3)keepAliveTime:對非核心執行緒沒有任務執行時最多保持多久時間會終止         4)workQueue:一個阻塞佇列,用來儲存等待執行的任務             ArrayBlockingQueue:基於陣列的先進先出佇列,此佇列建立時必須指定大小;             LinkedBlockQueue:基於連結串列的先進先出佇列,如果建立時沒有指定此佇列大小,則預設為Integer.MAX_VALUE;             SynchronousQueue:這個佇列比較特殊,它不會儲存提交的任務,而是將直接新建一個執行緒來執行新來的任務         5)threadFactory:執行緒工廠         6)handler:表示當拒絕處理任務時的策略             AbortPolicy:丟棄任務並丟擲異常             DiscardPolicy:丟棄任務不丟擲異常             DiscardOldestPolicy:丟棄佇列最前面的任務,重新嘗試執行任務             由呼叫執行緒處理該任務         7)策略             執行緒數量未達到corePoolSize,則新建一個核心執行緒執行任務             執行緒數量達到了corePoolSize,則進入佇列等待             佇列已滿,新建非核心執行緒執行任務             佇列已滿,匯流排程達到了maximumPoolSize則丟擲RejectedExcutionHandler異常     4、執行緒池分類         1)fixThreadPool:正規執行緒             有指定的執行緒數的執行緒池,有核心的執行緒,裡面有固定的執行緒數量,響應的速度快             沒有超時機制,佇列大小沒有限制,除非執行緒池關閉了核心執行緒才會回收         2)cacheThreadPool:快取執行緒池             只有非核心執行緒,最大執行緒數很大有超時回收機制             沒有考慮到系統的實際記憶體大小         3)singleThreadPool:單執行緒執行緒池             只有一個核心執行緒,不處理併發的操作,不會被回收         4)ScheduledThreadPool             有延遲執行和週期重複執行的執行緒池,核心執行緒池固定,非核心執行緒池不限,閒置時會回收。     5、可能出現的危險         死鎖、資源不足、併發錯誤、執行緒洩漏、請求過載、

    6、核心執行緒         核心執行緒預設情況下會一直存活線上程池中,即使這個核心執行緒啥也不幹(閒置狀態)。         執行緒池新建執行緒的時候,如果當前執行緒總數小於corePoolSize,則新建的是核心執行緒,如果超過corePoolSize,則新建的是非核心執行緒;allowCoreThreadTimeOut設定此項可以讓核心執行緒閒置狀態下回收     7、新增任務         ThreadPoolExecutor.execute(Runnable command)     8、執行緒池的關閉         shutdown():不會立即關閉,是等待所有任務快取佇列中的任務都執行完後才終止,但也不會接受新的執行緒         shutdownNow():立即終止執行緒池,嘗試打斷正在執行的任務,並且清空任務快取佇列,返回尚未執行的任務