Java并發(fā)編程學(xué)習(xí)筆記

線程池

策略

  1. 當(dāng)線程數(shù)量未達(dá)到核心線程數(shù)量,直接啟動(dòng)一個(gè)核心線程來執(zhí)行任務(wù)。
  2. 如果線程數(shù)量已達(dá)到或者超過核心線程的數(shù)量,任務(wù)被插入到任務(wù)隊(duì)列中排隊(duì)執(zhí)行。
  3. 如果在步驟2中無法將任務(wù)插入到任務(wù)隊(duì)列中,這往往是由于任務(wù)隊(duì)列已滿,這時(shí)候如果線程數(shù)量未達(dá)到線程池規(guī)定的最大值,會(huì)立刻啟動(dòng)一個(gè)非核心線程來執(zhí)行任務(wù)。
  4. 如果步驟3中線程數(shù)量達(dá)到最大值,就拒絕執(zhí)行此任務(wù)。

模式
并發(fā)編程中經(jīng)常使用消費(fèi)者和生產(chǎn)者模式,通過一個(gè)容器來解決生產(chǎn)者和消費(fèi)者的強(qiáng)耦合問題。大多數(shù)設(shè)計(jì)模式都會(huì)找出一個(gè)第三者進(jìn)行解耦。

優(yōu)點(diǎn)

  1. 重用線程池中的線程
  2. 有效控制線程池的最大并發(fā)數(shù)
  3. 對(duì)線程進(jìn)行有效的管理,并提供定時(shí)執(zhí)行及制定間隔循環(huán)執(zhí)行等功能。

備注
如果已知曉策略,沒有必要記優(yōu)點(diǎn)。因?yàn)閮?yōu)點(diǎn)可直接由策略推導(dǎo)出來。

Executor框架

Executor作為用戶級(jí)的調(diào)度器,用于將任務(wù)映射為固定數(shù)量的線程。Executor框架主要由3大部分組成:

  1. 任務(wù)。包括被執(zhí)行任務(wù)需要實(shí)現(xiàn)的接口:Runnable或Callable接口。Runnable不返回結(jié)果,而Callable返回。
  2. 任務(wù)的執(zhí)行。包括任務(wù)執(zhí)行機(jī)制的核心接口Executor,以及繼承自Executor的ExecutorService接口。ThreadPoolExecutor及ScheduledThreadPoolExecutor實(shí)現(xiàn)了ExecutorService接口。ScheduledThreadPoolExecutor主要用來執(zhí)行定期或延遲的任務(wù)。
  3. 異步計(jì)算的結(jié)果。包括接口Future和實(shí)現(xiàn)Future接口的FutureTask接口。FutureTask是一個(gè)可對(duì)任務(wù)進(jìn)行狀態(tài)干預(yù)的Runnable異步對(duì)象。包括超時(shí)處理/取消任務(wù)/同步狀態(tài)等干預(yù)。

注意參數(shù)
keepAliveTime
線程活動(dòng)保持時(shí)間。線程池中非核心的工作線程空閑后保持存活時(shí)間。默認(rèn)核心線程會(huì)在線程池中一直存活,即使處于閑置狀態(tài)。

線程運(yùn)行狀態(tài)變遷

線程運(yùn)行狀態(tài)變遷圖

(1)BLOCKED(等待獲取鎖時(shí)進(jìn)入的狀態(tài))
synchronized

(2)WAITING(通過wait方法進(jìn)入的等待)
當(dāng)wait,join,park方法調(diào)用時(shí),進(jìn)入waiting狀態(tài)。前提是這個(gè)線程已經(jīng)擁有鎖了。進(jìn)入該狀態(tài)表示當(dāng)前線程需要等待其他線程做出一些特定動(dòng)作(通知或中斷)。

blocked和waiting狀態(tài)的區(qū)別是:
A、blocked是虛擬機(jī)認(rèn)為程序還不能進(jìn)入某個(gè)區(qū)域,因?yàn)橥瑫r(shí)進(jìn)去就會(huì)有問題,這是一塊臨界區(qū)。
B、發(fā)生wait等操作的先決條件是要進(jìn)入臨界區(qū),也就是線程已經(jīng)拿到鎖了,自己可能進(jìn)去做了一些事情,但此時(shí)通過判定業(yè)務(wù)上的參數(shù),發(fā)現(xiàn)還有一些其他配合的資源沒有準(zhǔn)備充分,那么自己就等等再做其他事情。

(3)TIMED_WAITING(通過sleep或wait timeout方法進(jìn)入的限期等待的狀態(tài))
通過wait(t),sleep(t),join(t),parkNanos,parkUntil等方法進(jìn)入此狀態(tài)。當(dāng)時(shí)間達(dá)到時(shí)觸發(fā)線程回到工作狀態(tài)Runnable。

Thread.yield( )方法會(huì)將當(dāng)前線程的可執(zhí)行時(shí)間釋放,從運(yùn)行中的狀態(tài)變?yōu)榫途w狀態(tài)。

Interrupted中斷

中斷不屬于狀態(tài),中斷可以理解為線程的一個(gè)標(biāo)識(shí)位屬性,表示一個(gè)運(yùn)行中的線程是否被其他線程進(jìn)行了中斷操作。

在waiting狀態(tài)下,如果發(fā)生了interrupt操作,則處于該狀態(tài)的線程在內(nèi)部會(huì)拋出一個(gè)InterruptedException,這個(gè)異常應(yīng)當(dāng)在run方法內(nèi)捕獲,使得run方法正常地執(zhí)行完成,當(dāng)然捕獲異常后,是決定讓線程繼續(xù)運(yùn)行,還是結(jié)束等要根據(jù)業(yè)務(wù)場(chǎng)景才處理。

interrupt只對(duì)處于waiting或timed_waiting狀態(tài)的線程起作用,對(duì)其他狀態(tài)不起作用。

并發(fā)/并行/線程/異步

  1. 并行(parallel):在操作系統(tǒng)中,一組程序按獨(dú)立異步的速度執(zhí)行,無論從微觀還是宏觀,程序都是一起執(zhí)行的。

  2. 并發(fā)(concurrent):在操作系統(tǒng)中,是指一個(gè)時(shí)間段中有幾個(gè)程序都處于已啟動(dòng)運(yùn)行到運(yùn)行完畢之間,且這幾個(gè)程序都是在同一個(gè)處理機(jī)上運(yùn)行,但任一個(gè)時(shí)刻點(diǎn)上只有一個(gè)程序在處理機(jī)上運(yùn)行。其中兩種并發(fā)關(guān)系分別是同步和互斥:

2.1 互斥:進(jìn)程間相互排斥的使用臨界資源的現(xiàn)象,就叫互斥。
2.2 同步:進(jìn)程之間的關(guān)系不是相互排斥臨界資源的關(guān)系,而是相互依賴的關(guān)系。進(jìn)一步的說明:就是前一個(gè)進(jìn)程的輸出作為后一個(gè)進(jìn)程的輸入,當(dāng)?shù)谝粋€(gè)進(jìn)程沒有輸出時(shí)第二個(gè)進(jìn)程必須等待。具有同步關(guān)系的一組并發(fā)進(jìn)程相互發(fā)送的信息稱為消息或事件。

并行的關(guān)鍵是擁有同時(shí)處理多個(gè)任務(wù)的能力。而并行的關(guān)鍵是擁有處理多個(gè)任務(wù)的能力,不一定要同時(shí)。

  1. 線程: 線程本質(zhì)上是進(jìn)程中一段并發(fā)運(yùn)行的代碼,所以線程需要操作系統(tǒng)投入CPU資源來運(yùn)行和調(diào)度。
    線程都擁有各自的計(jì)數(shù)器、堆棧和局部變量等屬性,并且能夠訪問共享的內(nèi)存變量。一個(gè)線程在一個(gè)時(shí)刻只能運(yùn)行在一個(gè)處理器核心上。
    多線程中每個(gè)線程的處理程序依然是順序執(zhí)行。多線程可以實(shí)現(xiàn)線程間的切換執(zhí)行。

  2. 異步:異步使用回調(diào)的方式進(jìn)行處理。異步是最終目的,多線程只是我們實(shí)現(xiàn)異步的一種手段。

  3. 上下文切換:任務(wù)從保存到再加載的過程就是一次上下文切換。
    參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容