成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

java自帶線程池代碼,Java使用線程池

Java線程池?

線程池是一種多線程處理形式,處理過程中將任務添加隊列,然后在創(chuàng)建線程后自動啟動這些任務,每個線程都使用默認的堆棧大小,以默認的優(yōu)先級運行,并處在多線程單元中,如果某個線程在托管代碼中空閑,則線程池將插入另一個輔助線程來使所有處理器保持繁忙。如果所有線程池都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間后輔助線程的數(shù)目永遠不會超過最大值。超過最大值的線程可以排隊,但他們要等到其他線程完成后才能啟動。

創(chuàng)新互聯(lián)專注于頭屯河企業(yè)網(wǎng)站建設,響應式網(wǎng)站建設,商城網(wǎng)站建設。頭屯河網(wǎng)站建設公司,為頭屯河等地區(qū)提供建站服務。全流程按需規(guī)劃網(wǎng)站,專業(yè)設計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務

java里面的線程池的頂級接口是Executor,Executor并不是一個線程池,而只是一個執(zhí)行線程的工具,而真正的線程池是ExecutorService。

java中的有哪些線程池?

1.newCachedThreadPool創(chuàng)建一個可緩存線程池程

2.newFixedThreadPool 創(chuàng)建一個定長線程池

3.newScheduledThreadPool 創(chuàng)建一個定長線程池

4.newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池

————————————————

java線程池怎么實現(xiàn)

要想理解清楚java線程池實現(xiàn)原理,明白下面幾個問題就可以了:

(1):線程池存在哪些狀態(tài),這些狀態(tài)之間是如何進行切換的呢?

(2):線程池的種類有哪些?

(3):創(chuàng)建線程池需要哪些參數(shù),這些參數(shù)的具體含義是什么?

(4):將任務添加到線程池之后運行流程?

(5):線程池是怎么做到重用線程的呢?

(6):線程池的關閉

首先回答第一個問題:線程池存在哪些狀態(tài);

查看ThreadPoolExecutor源碼便知曉:

[java]?view plain?copy

//?runState?is?stored?in?the?high-order?bits

private?static?final?int?RUNNING????=?-1??COUNT_BITS;

private?static?final?int?SHUTDOWN???=??0??COUNT_BITS;

private?static?final?int?STOP???????=??1??COUNT_BITS;

private?static?final?int?TIDYING????=??2??COUNT_BITS;

private?static?final?int?TERMINATED?=??3??COUNT_BITS;

存在5種狀態(tài):

1Running:可以接受新任務,同時也可以處理阻塞隊列里面的任務;

2Shutdown:不可以接受新任務,但是可以處理阻塞隊列里面的任務;

3Stop:不可以接受新任務,也不處理阻塞隊列里面的任務,同時還中斷正在處理的任務;

4Tidying:屬于過渡階段,在這個階段表示所有的任務已經(jīng)執(zhí)行結(jié)束了,當前線程池中是不存在有效的線程的,并且將要調(diào)用terminated方法;

5Terminated:終止狀態(tài),這個狀態(tài)是在調(diào)用完terminated方法之后所處的狀態(tài);

那么這5種狀態(tài)之間是如何進行轉(zhuǎn)換的呢?查看ThreadPoolExecutor源碼里面的注釋便可以知道啦:

[java]?view plain?copy

*?RUNNING?-?SHUTDOWN

*????On?invocation?of?shutdown(),?perhaps?implicitly?in?finalize()

*?(RUNNING?or?SHUTDOWN)?-?STOP

*????On?invocation?of?shutdownNow()

*?SHUTDOWN?-?TIDYING

*????When?both?queue?and?pool?are?empty

*?STOP?-?TIDYING

*????When?pool?is?empty

*?TIDYING?-?TERMINATED

*????When?the?terminated()?hook?method?has?completed

從上面可以看到,在調(diào)用shutdown方法的時候,線程池狀態(tài)會從Running轉(zhuǎn)換成Shutdown;在調(diào)用shutdownNow方法的時候,線程池狀態(tài)會從Running/Shutdown轉(zhuǎn)換成Stop;在阻塞隊列為空同時線程池為空的情況下,線程池狀態(tài)會從Shutdown轉(zhuǎn)換成Tidying;在線程池為空的情況下,線程池狀態(tài)會從Stop轉(zhuǎn)換成Tidying;當調(diào)用terminated方法之后,線程池狀態(tài)會從Tidying轉(zhuǎn)換成Terminate;

在明白了線程池的各個狀態(tài)以及狀態(tài)之間是怎么進行切換之后,我們來看看第二個問題,線程池的種類:

(1):CachedThreadPool:緩存線程池,該類線程池中線程的數(shù)量是不確定的,理論上可以達到Integer.MAX_VALUE個,這種線程池中的線程都是非核心線程,既然是非核心線程,那么就存在超時淘汰機制了,當里面的某個線程空閑時間超過了設定的超時時間的話,就會回收掉該線程;

(2):FixedThreadPool:固定線程池,這類線程池中是只存在核心線程的,對于核心線程來說,如果我們不設置allowCoreThreadTimeOut屬性的話是不存在超時淘汰機制的,這類線程池中的corePoolSize的大小是等于maximumPoolSize大小的,也就是說,如果線程池中的線程都處于活動狀態(tài)的話,如果有新任務到來,他是不會開辟新的工作線程來處理這些任務的,只能將這些任務放到阻塞隊列里面進行等到,直到有核心線程空閑為止;

(3):ScheduledThreadPool:任務線程池,這種線程池中核心線程的數(shù)量是固定的,而對于非核心線程的數(shù)量是不限制的,同時對于非核心線程是存在超時淘汰機制的,主要適用于執(zhí)行定時任務或者周期性任務的場景;

(4):SingleThreadPool:單一線程池,線程池里面只有一個線程,同時也不存在非核心線程,感覺像是FixedThreadPool的特殊版本,他主要用于確保任務在同一線程中的順序執(zhí)行,有點類似于進行同步吧;

接下來我們來看第三個問題,創(chuàng)建線程池需要哪些參數(shù):

同樣查看ThreadPoolExecutor源碼,查看創(chuàng)建線程池的構(gòu)造函數(shù):

[java]?view plain?copy

public?ThreadPoolExecutor(int?corePoolSize,

int?maximumPoolSize,

long?keepAliveTime,

TimeUnit?unit,

BlockingQueueRunnable?workQueue,

ThreadFactory?threadFactory,

RejectedExecutionHandler?handler)

不管你調(diào)用的是ThreadPoolExecutor的哪個構(gòu)造函數(shù),最終都會執(zhí)行到這個構(gòu)造函數(shù)的,這個構(gòu)造函數(shù)有7個參數(shù),正是由于對這7個參數(shù)值的賦值不同,造成生成不同類型的線程池,比如我們常見的CachedThreadPoolExecutor、FixedThreadPoolExecutor

SingleThreadPoolExecutor、ScheduledThreadPoolExecutor,我們老看看這幾個參數(shù)的具體含義:

1corePoolSize:線程池中核心線程的數(shù)量;當提交一個任務到線程池的時候,線程池會創(chuàng)建一個線程來執(zhí)行執(zhí)行任務,即使有其他空閑的線程存在,直到線程數(shù)達到corePoolSize時不再創(chuàng)建,這時候會把提交的新任務放入到阻塞隊列中,如果調(diào)用了線程池的preStartAllCoreThreads方法,則會在創(chuàng)建線程池的時候初始化出來核心線程;

2maximumPoolSize:線程池允許創(chuàng)建的最大線程數(shù);如果阻塞隊列已經(jīng)滿了,同時已經(jīng)創(chuàng)建的線程數(shù)小于最大線程數(shù)的話,那么會創(chuàng)建新的線程來處理阻塞隊列中的任務;

3keepAliveTime:線程活動保持時間,指的是工作線程空閑之后繼續(xù)存活的時間,默認情況下,這個參數(shù)只有線程數(shù)大于corePoolSize的時候才會起作用,即當線程池中的線程數(shù)目大于corePoolSize的時候,如果某一個線程的空閑時間達到keepAliveTime,那么這個線程是會被終止的,直到線程池中的線程數(shù)目不大于corePoolSize;如果調(diào)用allowCoreThreadTimeOut的話,在線程池中線程數(shù)量不大于corePoolSize的時候,keepAliveTime參數(shù)也可以起作用的,知道線程數(shù)目為0為止;

4unit:參數(shù)keepAliveTime的時間單位;

5workQueue:阻塞隊列;用于存儲等待執(zhí)行的任務,有四種阻塞隊列類型,ArrayBlockingQueue(基于數(shù)組的有界阻塞隊列)、LinkedBlockingQueue(基于鏈表結(jié)構(gòu)的阻塞隊列)、SynchronousQueue(不存儲元素的阻塞隊列)、PriorityBlockingQueue(具有優(yōu)先級的阻塞隊列);

6threadFactory:用于創(chuàng)建線程的線程工廠;

7handler:當阻塞隊列滿了,且沒有空閑線程的情況下,也就是說這個時候,線程池中的線程數(shù)目已經(jīng)達到了最大線程數(shù)量,處于飽和狀態(tài),那么必須采取一種策略來處理新提交的任務,我們可以自己定義處理策略,也可以使用系統(tǒng)已經(jīng)提供給我們的策略,先來看看系統(tǒng)為我們提供的4種策略,AbortPolicy(直接拋出異常)、CallerRunsPolicy(只有調(diào)用者所在的線程來運行任務)、DiscardOldestPolicy(丟棄阻塞隊列中最近的一個任務,并執(zhí)行當前任務)、Discard(直接丟棄);

接下來就是將任務添加到線程池之后的運行流程了;

我們可以調(diào)用submit或者execute方法,兩者最大的區(qū)別在于,調(diào)用submit方法的話,我們可以傳入一個實現(xiàn)Callable接口的對象,進而能在當前任務執(zhí)行結(jié)束之后通過Future對象獲得任務的返回值,submit內(nèi)部實際上還是執(zhí)行的execute方法;而調(diào)用execute方法的話,是不能獲得任務執(zhí)行結(jié)束之后的返回值的;此外,調(diào)用submit方法的話是可以拋出異常的,但是調(diào)用execute方法的話,異常在其內(nèi)部得到了消化,也就是說異常在其內(nèi)部得到了處理,不會向外傳遞的;

因為submit方法最終也是會執(zhí)行execute方法的,因此我們只需要了解execute方法就可以了:

在execute方法內(nèi)部會分三種情況來進行處理:

1:首先判斷當前線程池中的線程數(shù)量是否小于corePoolSize,如果小于的話,則直接通過addWorker方法創(chuàng)建一個新的Worker對象來執(zhí)行我們當前的任務;

2:如果說當前線程池中的線程數(shù)量大于corePoolSize的話,那么會嘗試將當前任務添加到阻塞隊列中,然后第二次檢查線程池的狀態(tài),如果線程池不在Running狀態(tài)的話,會將剛剛添加到阻塞隊列中的任務移出,同時拒絕當前任務請求;如果第二次檢查發(fā)現(xiàn)當前線程池處于Running狀態(tài)的話,那么會查看當前線程池中的工作線程數(shù)量是否為0,如果為0的話,就會通過addWorker方法創(chuàng)建一個Worker對象出來處理阻塞隊列中的任務;

3:如果原先線程池就不處于Running狀態(tài)或者我們剛剛將當前任務添加到阻塞隊列的時候出現(xiàn)錯誤的話,那么會去嘗試通過addWorker創(chuàng)建新的Worker來處理當前任務,如果添加失敗的話,則拒絕當前任務請求;

可以看到在上面的execute方法中,我們僅僅只是檢查了當前線程池中的線程數(shù)量有沒有超過corePoolSize的情況,那么當前線程池中的線程數(shù)量有沒有超過maximumPoolSize是在哪里檢測的呢?實際上是在addWorker方法里面了,我們可以看下addWorker里面的一段代碼:

[java]?view plain?copy

if?(wc?=?CAPACITY?||

wc?=?(core???corePoolSize?:?maximumPoolSize))

return?false;

如果當前線程數(shù)量超過maximumPoolSize的話,直接就會調(diào)用return方法,返回false;

其實到這里我們很明顯可以知道,一個線程池中線程的數(shù)量實際上就是這個線程池中Worker的數(shù)量,如果Worker的大小超過了corePoolSize,那么任務都在阻塞隊列里面了,Worker是Java對我們?nèi)蝿盏囊粋€封裝類,他的聲明是醬紫的:

[java]?view plain?copy

private?final?class?Worker

extends?AbstractQueuedSynchronizer

implements?Runnable

可以看到他實現(xiàn)了Runnable接口,他是在addWorker方法里面通過new Worker(firstTask)創(chuàng)建的,我們來看看他的構(gòu)造函數(shù)就知道了:

[java]?view plain?copy

Worker(Runnable?firstTask)?{

setState(-1);?//?inhibit?interrupts?until?runWorker

this.firstTask?=?firstTask;

this.thread?=?getThreadFactory().newThread(this);

}

而這里的firstTask其實就是我們調(diào)用execute或者submit的時候傳入的那個參數(shù)罷了,一般來說這些參數(shù)是實現(xiàn)Callable或者Runnable接口的;

在通過addWorker方法創(chuàng)建出來Worker對象之后,這個方法的最后會執(zhí)行Worker內(nèi)部thread屬性的start方法,而這個thread屬性實際上就是封裝了Worker的Thread,執(zhí)行他的start方法實際上執(zhí)行的是Worker的run方法,因為Worker是實現(xiàn)了Runnable接口的,在run方法里面就會執(zhí)行runWorker方法,而runWorker方法里面首先會判斷當前我們傳入的任務是否為空,不為空的話直接就會執(zhí)行我們通過execute或者submit方法提交的任務啦,注意一點就是我們雖然會通過submit方法提交實現(xiàn)了Callable接口的對象,但是在調(diào)用submit方法的時候,其實是會將Callable對象封裝成實現(xiàn)了Runnable接口對象的,不信我們看看submit方法源碼是怎么實現(xiàn)的:

[java]?view plain?copy

public?T?FutureT?submit(CallableT?task)?{

if?(task?==?null)?throw?new?NullPointerException();

RunnableFutureT?ftask?=?newTaskFor(task);

execute(ftask);

return?ftask;

}

看到?jīng)]有呢,實際上在你傳入實現(xiàn)了Callable接口對象的時候,在submit方法里面是會將其封裝成RunnableFuture對象的,而RunnableFuture接口是繼承了Runnable接口的;那么說白了其實就是直接執(zhí)行我們提交任務的run方法了;如果為空的話,則會通過getTask方法從阻塞隊列里面拿出一個任務去執(zhí)行;在任務執(zhí)行結(jié)束之后繼續(xù)從阻塞隊列里面拿任務,直到getTask的返回值為空則退出runWorker內(nèi)部循環(huán),那么什么情況下getTask返回為空呢?查看getTask方法的源碼注釋可以知道:在Worker必須需要退出的情況下getTask會返回空,具體什么情況下Worker會退出呢?(1):當Worker的數(shù)量超過maximumPoolSize的時候;(2):當線程池狀態(tài)為Stop的時候;(3):當線程池狀態(tài)為Shutdown并且阻塞隊列為空的時候;(4):使用等待超時時間從阻塞隊列中拿數(shù)據(jù),但是超時之后仍然沒有拿到數(shù)據(jù);

如果runWorker方法退出了它里面的循環(huán),那么就說明當前阻塞隊列里面是沒有任務可以執(zhí)行的了,你可以看到在runWorker方法內(nèi)部的finally語句塊中執(zhí)行了processWorkerExit方法,用來對Worker對象進行回收操作,這個方法會傳入一個參數(shù)表示需要刪除的Worker對象;在進行Worker回收的時候會調(diào)用tryTerminate方法來嘗試關閉線程池,在tryTerminate方法里面會檢查是否有Worker在工作,檢查線程池的狀態(tài),沒問題的話就會將當前線程池的狀態(tài)過渡到Tidying,之后調(diào)用terminated方法,將線程池狀態(tài)更新到Terminated;

從上面的分析中,我們可以看出線程池運行的4個階段:

(1):poolSize corePoolSize,則直接創(chuàng)建新的線程(核心線程)來執(zhí)行當前提交的任務;

(2):poolSize = corePoolSize,并且此時阻塞隊列沒有滿,那么會將當前任務添加到阻塞隊列中,如果此時存在工作線程(非核心線程)的話,那么會由工作線程來處理該阻塞隊列中的任務,如果此時工作線程數(shù)量為0的話,那么會創(chuàng)建一個工作線程(非核心線程)出來;

(3):poolSize = corePoolSize,并且此時阻塞隊列已經(jīng)滿了,那么會直接創(chuàng)建新的工作線程(非核心線程)來處理阻塞隊列中的任務;

(4):poolSize = maximumPoolSize,并且此時阻塞隊列也滿了的話,那么會觸發(fā)拒絕機制,具體決絕策略采用的是什么就要看我們創(chuàng)建ThreadPoolExecutor的時候傳入的RejectExecutionHandler參數(shù)了;

接下來就是線程池是怎么做到重用線程的呢?

個人認為線程池里面重用線程的工作是在getTask里面實現(xiàn)的,在getTask里面是存在兩個for死循環(huán)嵌套的,他會不斷的從阻塞對列里面取出需要執(zhí)行的任務,返回給我們的runWorker方法里面,而在runWorker方法里面只要getTask返回的任務不是空就會執(zhí)行該任務的run方法來處理它,這樣一直執(zhí)行下去,直到getTask返回空為止,此時的情況就是阻塞隊列里面沒有任務了,這樣一個線程處理完一個任務之后接著再處理阻塞隊列中的另一個任務,當然在線程池中的不同線程是可以并發(fā)處理阻塞隊列中的任務的,最后在阻塞隊列內(nèi)部不存在任務的時候會去判斷是否需要回收Worker對象,其實Worker對象的個數(shù)就是線程池中線程的個數(shù),至于什么情況才需要回收,上面已經(jīng)說了,就是四種情況了;

最后就是線程池是怎樣被關閉的呢?

涉及到線程池的關閉,需要用到兩個方法,shutdown和shutdownNow,他們都是位于ThreadPoolExecutor里面的,對于shutdown的話,他會將線程池狀態(tài)切換成Shutdown,此時是不會影響對阻塞隊列中任務執(zhí)行的,但是會拒絕執(zhí)行新加進來的任務,同時會回收閑置的Worker;而shutdownNow方法會將線程池狀態(tài)切換成Stop,此時既不會再去處理阻塞隊列里面的任務,也不會去處理新加進來的任務,同時會回收所有Worker;

java 怎么實現(xiàn)線程池

最簡單的可以利用java.util.concurrent.Executors

調(diào)用Executors.newCachedThreadPool()獲取緩沖式線程池

Executors.newFixedThreadPool(int nThreads)獲取固定大小的線程池

java線程池怎么實現(xiàn)的

線程池簡介:

多線程技術(shù)主要解決處理器單元內(nèi)多個線程執(zhí)行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。

假設一個服務器完成一項任務所需時間為:T1 創(chuàng)建線程時間,T2 在線程中執(zhí)行任務的時間,T3 銷毀線程時間。

如果:T1 + T3 遠大于 T2,則可以采用線程池,以提高服務器性能。

一個線程池包括以下四個基本組成部分:

1、線程池管理器(ThreadPool):用于創(chuàng)建并管理線程池,包括 創(chuàng)建線程池,銷毀線程池,添加新任務;

2、工作線程(PoolWorker):線程池中線程,在沒有任務時處于等待狀態(tài),可以循環(huán)的執(zhí)行任務;

3、任務接口(Task):每個任務必須實現(xiàn)的接口,以供工作線程調(diào)度任務的執(zhí)行,它主要規(guī)定了任務的入口,任務執(zhí)行完后的收尾工作,任務的執(zhí)行狀態(tài)等;

4、任務隊列(taskQueue):用于存放沒有處理的任務。提供一種緩沖機制。

線程池技術(shù)正是關注如何縮短或調(diào)整T1,T3時間的技術(shù),從而提高服務器程序性能的。它把T1,T3分別安排在服務器程序的啟動和結(jié)束的時間段或者一些空閑的時間段,這樣在服務器程序處理客戶請求時,不會有T1,T3的開銷了。

線程池不僅調(diào)整T1,T3產(chǎn)生的時間段,而且它還顯著減少了創(chuàng)建線程的數(shù)目,看一個例子:

假設一個服務器一天要處理50000個請求,并且每個請求需要一個單獨的線程完成。在線程池中,線程數(shù)一般是固定的,所以產(chǎn)生線程總數(shù)不會超過線程池中線程的數(shù)目,而如果服務器不利用線程池來處理這些請求則線程總數(shù)為50000。一般線程池大小是遠小于50000。所以利用線程池的服務器程序不會為了創(chuàng)建50000而在處理請求時浪費時間,從而提高效率。

代碼實現(xiàn)中并沒有實現(xiàn)任務接口,而是把Runnable對象加入到線程池管理器(ThreadPool),然后剩下的事情就由線程池管理器(ThreadPool)來完成了

package?mine.util.thread;??

import?java.util.LinkedList;??

import?java.util.List;??

/**?

*?線程池類,線程管理器:創(chuàng)建線程,執(zhí)行任務,銷毀線程,獲取線程基本信息?

*/??

public?final?class?ThreadPool?{??

//?線程池中默認線程的個數(shù)為5??

private?static?int?worker_num?=?5;??

//?工作線程??

private?WorkThread[]?workThrads;??

//?未處理的任務??

private?static?volatile?int?finished_task?=?0;??

//?任務隊列,作為一個緩沖,List線程不安全??

private?ListRunnable?taskQueue?=?new?LinkedListRunnable();??

private?static?ThreadPool?threadPool;??

//?創(chuàng)建具有默認線程個數(shù)的線程池??

private?ThreadPool()?{??

this(5);??

}??

//?創(chuàng)建線程池,worker_num為線程池中工作線程的個數(shù)??

private?ThreadPool(int?worker_num)?{??

ThreadPool.worker_num?=?worker_num;??

workThrads?=?new?WorkThread[worker_num];??

for?(int?i?=?0;?i??worker_num;?i++)?{??

workThrads[i]?=?new?WorkThread();??

workThrads[i].start();//?開啟線程池中的線程??

}??

}??

//?單態(tài)模式,獲得一個默認線程個數(shù)的線程池??

public?static?ThreadPool?getThreadPool()?{??

return?getThreadPool(ThreadPool.worker_num);??

}??

//?單態(tài)模式,獲得一個指定線程個數(shù)的線程池,worker_num(0)為線程池中工作線程的個數(shù)??

//?worker_num=0創(chuàng)建默認的工作線程個數(shù)??

public?static?ThreadPool?getThreadPool(int?worker_num1)?{??

if?(worker_num1?=?0)??

worker_num1?=?ThreadPool.worker_num;??

if?(threadPool?==?null)??

threadPool?=?new?ThreadPool(worker_num1);??

return?threadPool;??

}??

//?執(zhí)行任務,其實只是把任務加入任務隊列,什么時候執(zhí)行有線程池管理器覺定??

public?void?execute(Runnable?task)?{??

synchronized?(taskQueue)?{??

taskQueue.add(task);??

taskQueue.notify();??

}??

}??

//?批量執(zhí)行任務,其實只是把任務加入任務隊列,什么時候執(zhí)行有線程池管理器覺定??

public?void?execute(Runnable[]?task)?{??

synchronized?(taskQueue)?{??

for?(Runnable?t?:?task)??

taskQueue.add(t);??

taskQueue.notify();??

}??

}??

//?批量執(zhí)行任務,其實只是把任務加入任務隊列,什么時候執(zhí)行有線程池管理器覺定??

public?void?execute(ListRunnable?task)?{??

synchronized?(taskQueue)?{??

for?(Runnable?t?:?task)??

taskQueue.add(t);??

taskQueue.notify();??

}??

}??

//?銷毀線程池,該方法保證在所有任務都完成的情況下才銷毀所有線程,否則等待任務完成才銷毀??

public?void?destroy()?{??

while?(!taskQueue.isEmpty())?{//?如果還有任務沒執(zhí)行完成,就先睡會吧??

try?{??

Thread.sleep(10);??

}?catch?(InterruptedException?e)?{??

e.printStackTrace();??

}??

}??

//?工作線程停止工作,且置為null??

for?(int?i?=?0;?i??worker_num;?i++)?{??

workThrads[i].stopWorker();??

workThrads[i]?=?null;??

}??

threadPool=null;??

taskQueue.clear();//?清空任務隊列??

}??

//?返回工作線程的個數(shù)??

public?int?getWorkThreadNumber()?{??

return?worker_num;??

}??

//?返回已完成任務的個數(shù),這里的已完成是只出了任務隊列的任務個數(shù),可能該任務并沒有實際執(zhí)行完成??

public?int?getFinishedTasknumber()?{??

return?finished_task;??

}??

//?返回任務隊列的長度,即還沒處理的任務個數(shù)??

public?int?getWaitTasknumber()?{??

return?taskQueue.size();??

}??

//?覆蓋toString方法,返回線程池信息:工作線程個數(shù)和已完成任務個數(shù)??

@Override??

public?String?toString()?{??

return?"WorkThread?number:"?+?worker_num?+?"??finished?task?number:"??

+?finished_task?+?"??wait?task?number:"?+?getWaitTasknumber();??

}??

/**?

*?內(nèi)部類,工作線程?

*/??

private?class?WorkThread?extends?Thread?{??

//?該工作線程是否有效,用于結(jié)束該工作線程??

private?boolean?isRunning?=?true;??

/*?

*?關鍵所在啊,如果任務隊列不空,則取出任務執(zhí)行,若任務隊列空,則等待?

*/??

@Override??

public?void?run()?{??

Runnable?r?=?null;??

while?(isRunning)?{//?注意,若線程無效則自然結(jié)束run方法,該線程就沒用了??

synchronized?(taskQueue)?{??

while?(isRunning??taskQueue.isEmpty())?{//?隊列為空??

try?{??

taskQueue.wait(20);??

}?catch?(InterruptedException?e)?{??

e.printStackTrace();??

}??

}??

if?(!taskQueue.isEmpty())??

r?=?taskQueue.remove(0);//?取出任務??

}??

if?(r?!=?null)?{??

r.run();//?執(zhí)行任務??

}??

finished_task++;??

r?=?null;??

}??

}??

//?停止工作,讓該線程自然執(zhí)行完run方法,自然結(jié)束??

public?void?stopWorker()?{??

isRunning?=?false;??

}??

}??

}

關于JAVA中自帶的線程池 創(chuàng)建問題

ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueueRunnable workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler)

參數(shù):

corePoolSize - 池中所保存的線程數(shù),包括空閑線程。

maximumPoolSize - 池中允許的最大線程數(shù)。

keepAliveTime - 當線程數(shù)大于核心時,此為終止前多余的空閑線程等待新任務的最長時間。

unit - keepAliveTime 參數(shù)的時間單位。

workQueue - 執(zhí)行前用于保持任務的隊列。此隊列僅保持由 execute 方法提交的 Runnable 任務。

threadFactory - 執(zhí)行程序創(chuàng)建新線程時使用的工廠。

handler - 由于超出線程范圍和隊列容量而使執(zhí)行被阻塞時所使用的處理程序。

RejectedExecutionHandler接口

無法由 ThreadPoolExecutor 執(zhí)行的任務的處理程序。

四個子類:

1.ThreadPoolExecutor.AbortPolicy --- 用于被拒絕任務的處理程序,它將拋出 RejectedExecutionException.

源碼如下:

/**

* A handler for rejected tasks that throws a

* ttRejectedExecutionException/tt.

*/

public static class AbortPolicy implements RejectedExecutionHandler {

/**

* Creates an ttAbortPolicy/tt.

*/

public AbortPolicy() { }

/**

* Always throws RejectedExecutionException.

* @param r the runnable task requested to be executed

* @param e the executor attempting to execute this task

* @throws RejectedExecutionException always.

*/

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

throw new RejectedExecutionException();

}

}

2.ThreadPoolExecutor.CallerRunsPolicy --- 用于被拒絕任務的處理程序,它直接在 execute 方法的調(diào)用線程中運行被拒絕的任務;如果執(zhí)行程序已關閉,則會丟棄該任務。

源碼如下:

/**

* A handler for rejected tasks that runs the rejected task

* directly in the calling thread of the ttexecute/tt method,

* unless the executor has been shut down, in which case the task

* is discarded.

*/

public static class CallerRunsPolicy implements RejectedExecutionHandler {

/**

* Creates a ttCallerRunsPolicy/tt.

*/

public CallerRunsPolicy() { }

/**

* Executes task r in the caller's thread, unless the executor

* has been shut down, in which case the task is discarded.

* @param r the runnable task requested to be executed

* @param e the executor attempting to execute this task

*/

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

if (!e.isShutdown()) {

r.run();

}

}

}

3.ThreadPoolExecutor.DiscardOldestPolicy --- 用于被拒絕任務的處理程序,它放棄最舊的未處理請求,然后重試 execute;如果執(zhí)行程序已關閉,則會丟棄該任務。

源碼如下:

/**

* A handler for rejected tasks that discards the oldest unhandled

* request and then retries ttexecute/tt, unless the executor

* is shut down, in which case the task is discarded.

*/

public static class DiscardOldestPolicy implements RejectedExecutionHandler {

/**

* Creates a ttDiscardOldestPolicy/tt for the given executor.

*/

public DiscardOldestPolicy() { }

/**

* Obtains and ignores the next task that the executor

* would otherwise execute, if one is immediately available,

* and then retries execution of task r, unless the executor

* is shut down, in which case task r is instead discarded.

* @param r the runnable task requested to be executed

* @param e the executor attempting to execute this task

*/

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

if (!e.isShutdown()) {

e.getQueue().poll();

e.execute(r);

}

}

}

4.ThreadPoolExecutor.DiscardPolicy --- 用于被拒絕任務的處理程序,默認情況下它將放棄被拒絕的任務。

源碼如下:

/**

* A handler for rejected tasks that silently discards the

* rejected task.

*/

public static class DiscardPolicy implements RejectedExecutionHandler {

/**

* Creates a ttDiscardPolicy/tt.

*/

public DiscardPolicy() { }

/**

* Does nothing, which has the effect of discarding task r.

* @param r the runnable task requested to be executed

* @param e the executor attempting to execute this task

*/

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

}

}

一個任務通過 execute(Runnable)方法被添加到線程池,任務就是一個 Runnable類型的對象,任務的執(zhí)行方法就是 Runnable類型對象的run()方法。

當一個任務通過execute(Runnable)方法欲添加到線程池時:

1.如果此時線程池中的數(shù)量小于corePoolSize,即使線程池中的線程都處于空閑狀態(tài),也要創(chuàng)建新的線程來處理被添加的任務。

2.如果此時線程池中的數(shù)量等于corePoolSize,但是緩沖隊列 workQueue未滿,那么任務被放入緩沖隊列。

3.如果此時線程池中的數(shù)量大于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數(shù)量小于maximumPoolSize,建新的線程來處理被添加的任務。

4.如果此時線程池中的數(shù)量大于corePoolSize,緩沖隊列workQueue滿,并且線程池中的數(shù)量等于maximumPoolSize,

那么通過handler所指定的策略來處理此任務。也就是:處理任務的優(yōu)先級為:核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,

如果三者都滿了,使用handler處理被拒絕的任務。

5.當線程池中的線程數(shù)量大于 corePoolSize時,如果某線程空閑時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態(tài)的調(diào)整池中的線程數(shù)

java,一個程序建立1000個線程,每一個線程加1到一個變量sum。

1、程序建立1000個線程,有可能造成系統(tǒng)創(chuàng)建大量線程而導致消耗完系統(tǒng)內(nèi)存,還會增加創(chuàng)建和銷毀線程上所花的時間以及系統(tǒng)資源的開銷

2、在創(chuàng)建線程數(shù)多的情況下,可以考慮使用線程池

以下是Java自帶的幾種線程池:

(1)、newFixedThreadPool 創(chuàng)建一個指定工作線程數(shù)量的線程池。

每當提交一個任務就創(chuàng)建一個工作線程,如果工作線程數(shù)量達到線程池初始的最大數(shù),則將提交的任務存入到池隊列中。

(2)、newCachedThreadPool 創(chuàng)建一個可緩存的線程池。

這種類型的線程池特點是:

1).工作線程的創(chuàng)建數(shù)量幾乎沒有限制(其實也有限制的,數(shù)目為Interger. MAX_VALUE), 這樣可靈活的往線程池中添加線程。

2).如果長時間沒有往線程池中提交任務,即如果工作線程空閑了指定的時間(默認為1分鐘),則該工作線程將自動終止。終止后,如果你又提交了新的任務,則線程池重新創(chuàng)建一個工作線程。

(3)、newSingleThreadExecutor 創(chuàng)建一個單線程化的Executor,即只創(chuàng)建唯一的工作者線程來執(zhí)行任務,如果這個線程異常結(jié)束,會有另一個取代它,保證順序執(zhí)行(我覺得這點是它的特色)。

單工作線程最大的特點是可保證順序地執(zhí)行各個任務,并且在任意給定的時間不會有多個線程是活動的 。

(4)、newScheduleThreadPool 創(chuàng)建一個定長的線程池,而且支持定時的以及周期性的任務執(zhí)行,類似于Timer。

3、示例代碼

package?test;??

import?java.util.concurrent.ExecutorService;??

import?java.util.concurrent.Executors;??

public?class?ThreadPoolExecutorTest?{??

public?static?void?main(String[]?args)?{??

ExecutorService?cachedThreadPool?=?Executors.newCachedThreadPool();??

for?(int?i?=?0;?i??1000;?i++)?{??

cachedThreadPool.execute(new?Runnable()?{??

public?void?run()?{??

//在這里執(zhí)行你需要的功能

}??

});??

}??

}??

}

當前名稱:java自帶線程池代碼,Java使用線程池
分享URL:http://jinyejixie.com/article20/dsseoco.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供標簽優(yōu)化、動態(tài)網(wǎng)站域名注冊、虛擬主機、企業(yè)建站、App設計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設
蓝山县| 阿鲁科尔沁旗| 江源县| 盘锦市| 金门县| 灵山县| 奉新县| 宝兴县| 海丰县| 宝兴县| 淄博市| 金坛市| 芷江| 大荔县| 临夏市| 天水市| 酒泉市| 三穗县| 东乌珠穆沁旗| 锦州市| 东兴市| 车致| 惠来县| 佛教| 滨州市| 威信县| 象山县| 嫩江县| 建平县| 林甸县| 滨海县| 潍坊市| 宁化县| 永修县| 万年县| 石首市| 江北区| 扬州市| 巴林左旗| 海伦市| 航空|