摘要:并發(fā)編程實(shí)戰(zhàn)水平很高,然而并不是本好書。一是多線程的控制,二是并發(fā)同步的管理。最后,使用和來關(guān)閉線程池,停止其中的線程。當(dāng)線程調(diào)用或等阻塞時,對這個線程調(diào)用會使線程醒來,并受到,且線程的中斷標(biāo)記被設(shè)置。
《Java并發(fā)編程實(shí)戰(zhàn)》水平很高,然而并不是本好書。組織混亂、長篇大論、難以消化,中文翻譯也較死板。這里是一篇批評此書的帖子,很是貼切。俗話說:“看到有這么多人罵你,我就放心了”。
然而知識總是要學(xué)的。這里就總結(jié)一下書中及網(wǎng)絡(luò)上的內(nèi)容,作為Java并發(fā)編程之旅的結(jié)束,不再浪費(fèi)時間了。
兩個部分這本書實(shí)際上可以分為兩個部分。一是多線程的控制,二是并發(fā)同步的管理。把它們?nèi)嘣谝黄穑悸泛茈y清晰。本文就先介紹第一部分,多線程的控制。
Thread和Runnable在Java 5.0之前,多線程編程就是直接操作Thread??梢詮?b>Thread類派生一個類,或者實(shí)現(xiàn)Runnable接口的run()方法,然后調(diào)用Thread.start()啟動線程。
線程的幾種狀態(tài):
Java 5.0增加了java.util.concurrent包,才有了線程池等強(qiáng)大的工具。
Java線程池參見Java線程池系列文章。本文略做總結(jié)。
阻塞隊(duì)列 BlockingQueue阻塞隊(duì)列,顧名思義,它在基本隊(duì)列的基礎(chǔ)上,還有阻塞的功能。即,如果隊(duì)列已滿,則入隊(duì)操作阻塞等待,直到有空位;如果隊(duì)列已空,則出隊(duì)操作阻塞等待,直到隊(duì)列有元素。相應(yīng)的方法分別為put()和take()。
阻塞隊(duì)列有幾種實(shí)現(xiàn):
ArrayBlockingQueue:基于數(shù)組結(jié)構(gòu)的有界阻塞隊(duì)列,按 FIFO(先進(jìn)先出)原則對元素進(jìn)行排序。
LinkedBlockingQueue:基于鏈表結(jié)構(gòu)的阻塞隊(duì)列,按FIFO排序元素,吞吐量通常要高于ArrayBlockingQueue。
SynchronousQueue:一個不存儲元素的阻塞隊(duì)列。每個插入操作必須等到另一個線程調(diào)用移除操作,否則插入操作一直處于阻塞狀態(tài),吞吐量通常要高于LinkedBlockingQueue。
PriorityBlockingQueue:一個具有優(yōu)先級的無限阻塞隊(duì)列。
自己實(shí)現(xiàn)線程池就是一個簡單的生產(chǎn)者、消費(fèi)者模型。線程池中的線程是消費(fèi)者,循環(huán)地從阻塞隊(duì)列中提取任務(wù),執(zhí)行任務(wù)。
Java線程池Java線程池的接口是ExecutorService,它有幾個實(shí)現(xiàn)。以ThreadPoolExecutor為例,它的使用方式是:
BlockingQueuequeue = new ArrayBlockingQueue (5); ExecutorService threadPoolExecutor = new ThreadPoolExecutor( corePoolSize, //初始線程數(shù) maxPoolSize, //最大線程數(shù) keepAliveTime, //空閑線程最大存活時間 TimeUnit.MILLISECONDS, //時間單位 queue // 任務(wù)的阻塞隊(duì)列 );
要使用這個線程池,可以使用它提供的如下方法:
execute(Runnable) 沒有返回值 。
submit(Runnable) 返回Future對象,代表未完成的結(jié)果(由于Runnable沒有返回值所以內(nèi)容為空)。
submit(Callable) 返回Future對象,代表未完成的結(jié)果。
invokeAny(Collection) 執(zhí)行所有任務(wù),返回第一個完成的結(jié)果。
invokeAll(Collection) 執(zhí)行所有任務(wù),返回Future對象列表。
最后,使用shutdown()和shutdownNow()來關(guān)閉線程池,停止其中的線程。前者采用后文講到的interrupt方式溫和關(guān)閉,后者則調(diào)用Thread.stop()強(qiáng)行關(guān)閉。
Executors類上面的線程池使用起來還是太具體了,還需要自己創(chuàng)建線程池,還要自己傳阻塞隊(duì)列進(jìn)去,不好用。于是Java提供了一個幫助類Executors,非常常用。
來看它的常用方法:
newFixedThreadPool(): 創(chuàng)建固定數(shù)量的線程池。
newCachedThreadPool(): 創(chuàng)建動態(tài)維護(hù)線程數(shù)的線程池。
newSingleThreadExecutor(): 創(chuàng)建單線程的線程池。
Callable接口和Future接口Runnable接口的問題在于沒有返回值,過于簡單了。因此加入了Callable接口。相比于Runnable,一是有返回值,二是可以拋出異常。
Future就是異步編程中對一個還沒有完成的任務(wù)的抽象,相當(dāng)于C#中的Task。同樣有cancel()、isDone()等方法,調(diào)用get()則阻塞地獲取結(jié)果。
FutureTask是Future的一個具體實(shí)現(xiàn)類,并且不光實(shí)現(xiàn)了Future,還實(shí)現(xiàn)了Runnable接口,使其用舊方式也可調(diào)用。具體可見 Runnable、Callable、Future、FutureTask的區(qū)別。
這是一個高級話題。Java建議不要用stop()粗暴地殺死線程,而是采用interrupt()這種溫和的方式。當(dāng)線程調(diào)用wait()或sleep()等阻塞時,對這個線程調(diào)用interrupt()會使線程醒來,并受到InterruptedException,且線程的中斷標(biāo)記被設(shè)置。如何處理這種情況取決于線程自己。具體參見這篇文章。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68538.html
摘要:前言并發(fā)編程的目的是讓程序跑的更快,但并不是啟動更多的線程,這個程序就跑的更快。盡可能降低上下文切換的次數(shù),有助于提高并發(fā)效率。死鎖并發(fā)編程中的另一挑戰(zhàn)是死鎖,會造成系統(tǒng)功能不可用。 前言 并發(fā)編程的目的是讓程序跑的更快,但并不是啟動更多的線程,這個程序就跑的更快。有以下幾種挑戰(zhàn)。 挑戰(zhàn)及方案 上下文切換 單核CPU上執(zhí)行多線程任務(wù),通過給每個線程分配CPU時間片的方式來實(shí)現(xiàn)這個機(jī)制。...
摘要:本文探討并發(fā)中的其它問題線程安全可見性活躍性等等。當(dāng)閉鎖到達(dá)結(jié)束狀態(tài)時,門打開并允許所有線程通過。在從返回時被叫醒時,線程被放入鎖池,與其他線程競爭重新獲得鎖。 本文探討Java并發(fā)中的其它問題:線程安全、可見性、活躍性等等。 在行文之前,我想先推薦以下兩份資料,質(zhì)量很高:極客學(xué)院-Java并發(fā)編程讀書筆記-《Java并發(fā)編程實(shí)戰(zhàn)》 線程安全 《Java并發(fā)編程實(shí)戰(zhàn)》中提到了太多的術(shù)語...
摘要:目前看的部分主要是這個關(guān)鍵字。語言提供了,保證了所有線程能看到共享變量最新的值。前綴的指令在多核處理器下會做兩件事情將當(dāng)前處理器緩存行的數(shù)據(jù)寫回到系統(tǒng)內(nèi)存。 這一章節(jié)的話,主要是講一下在并發(fā)操作中常見的volatile、synchronized以及原子操作的相關(guān)知識。 目前看的部分主要是volatile這個關(guān)鍵字。 volatile 根據(jù)Java語言規(guī)范第3版中對volatile的定義...
摘要:純分享直接上干貨操作系統(tǒng)并發(fā)支持進(jìn)程管理內(nèi)存管理文件系統(tǒng)系統(tǒng)進(jìn)程間通信網(wǎng)絡(luò)通信阻塞隊(duì)列數(shù)組有界隊(duì)列鏈表無界隊(duì)列優(yōu)先級有限無界隊(duì)列延時無界隊(duì)列同步隊(duì)列隊(duì)列內(nèi)存模型線程通信機(jī)制內(nèi)存共享消息傳遞內(nèi)存模型順序一致性指令重排序原則內(nèi)存語義線程 純分享 , 直接上干貨! 操作系統(tǒng)并發(fā)支持 進(jìn)程管理內(nèi)存管...
摘要:前言今天的筆記來了解一下原子操作以及中如何實(shí)現(xiàn)原子操作。概念原子本意是不能被進(jìn)一步分割的最小粒子,而原子操作意為不可被中斷的一個或一系列操作。處理器實(shí)現(xiàn)原子操作處理器會保證基本內(nèi)存操作的原子性。 showImg(https://segmentfault.com/img/bVVIRA?w=1242&h=536); 前言 今天的筆記來了解一下原子操作以及Java中如何實(shí)現(xiàn)原子操作。 概念 ...
閱讀 857·2021-11-18 10:07
閱讀 2367·2021-10-14 09:42
閱讀 5376·2021-09-22 15:45
閱讀 602·2021-09-03 10:29
閱讀 3483·2021-08-31 14:28
閱讀 1887·2019-08-30 15:56
閱讀 3050·2019-08-30 15:54
閱讀 1005·2019-08-29 11:32