java new thread参数_java线程池01-ThreadPoolExecutor构造方法参数的使用规则
為了更好的使用多線程,JDK提供了線程池供開發(fā)人員使用,目的在于減少線程的創(chuàng)建和銷毀次數(shù),以此達到線程的重復(fù)利用。
其中ThreadPoolExecutor是線程池中最核心的一個類,我們先簡單看一下這個類的繼承關(guān)系。
其中Executor是線程池的頂級接口,接口中只定義了一個方法? void execute(Runnable command);線程池的操作方法都是定義子在ExecutorService子接口中的,所以說ExecutorService是線程池真正的接口。
ThreadPoolExecutor提供了四個構(gòu)造方法,我們看一下參數(shù)最全的一個構(gòu)造函數(shù);
public ThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,
TimeUnit unit,
BlockingQueueworkQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {}
函數(shù)的參數(shù)含義如下:
corePoolSize: 線程池核心線程數(shù)
maximumPoolSize:線程池最大數(shù)
keepAliveTime: 空閑線程存活時間
unit: 時間單位
workQueue: 線程池所使用的緩沖隊列
threadFactory:線程池創(chuàng)建線程使用的工廠
handler: 線程池對拒絕任務(wù)的處理策略
本節(jié)我們主要對前五個參數(shù)中的corePoolSize,maximumPoolSize及workQueue是如何配合使用做出說明(keepAliveTime,unit主要對空閑線程的存活時間做的定義,見名知意,不再做出說明),以此來引出線程池的一些特性。
threadFactory和handler這兩個參數(shù)都有默認值,對于它們的用法將放到其它章節(jié)去做說明。
特性一:當池中正在運行的線程數(shù)(包括空閑線程)小于corePoolSize時,新建線程執(zhí)行任務(wù)。
下面用實驗來說明,代碼如下:
public classTestThreadPoolExecutor {public static voidmain(String[] args) {
ThreadPoolExecutor pool= new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS,new LinkedBlockingQueue<>(1));//任務(wù)1
pool.execute(newRunnable() {
@Overridepublic voidrun() {
System.out.println("-------------helloworld_001---------------" +Thread.currentThread().getName());
}
});try{//主線程睡2秒
Thread.sleep(2*1000);
}catch(InterruptedException e) {
e.printStackTrace();
}//任務(wù)2
pool.execute(newRunnable() {
@Overridepublic voidrun() {
System.out.println("-------------helloworld_002---------------" +Thread.currentThread().getName());
}
});
}
}
實驗結(jié)果如下:
實驗結(jié)果分析:
從實驗結(jié)果上可以看出,當執(zhí)行任務(wù)1的線程(thread-1)執(zhí)行完成之后,任務(wù)2并沒有去復(fù)用thread-1而是新建線程(thread-2)去執(zhí)行任務(wù)。
特性二:當池中正在運行的線程數(shù)大于等于corePoolSize時,新插入的任務(wù)進入workQueue排隊(如果workQueue長度允許),等待空閑線程來執(zhí)行。
下面用實驗來說明,代碼如下:
public classTestThreadPoolExecutor {public static voidmain(String[] args) {
ThreadPoolExecutor pool= new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));//任務(wù)1
pool.execute(newRunnable() {
@Overridepublic voidrun() {try{
Thread.sleep(3 * 1000);
System.out.println("-------------helloworld_001---------------" +Thread.currentThread().getName());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});//任務(wù)2
pool.execute(newRunnable() {
@Overridepublic voidrun() {try{
Thread.sleep(5 * 1000);
System.out.println("-------------helloworld_002---------------" +Thread.currentThread().getName());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});//任務(wù)3
pool.execute(newRunnable() {
@Overridepublic voidrun() {
System.out.println("-------------helloworld_003---------------" +Thread.currentThread().getName());
}
});
}
}
實驗結(jié)果如下:
實驗結(jié)果分析:
從實驗結(jié)果上看,任務(wù)3會等待任務(wù)1執(zhí)行完之后,有了空閑線程,才會執(zhí)行。并沒有新建線程執(zhí)行任務(wù)3,這時maximumPoolSize=3這個參數(shù)不起作用。
特性三:當隊列里的任務(wù)數(shù)達到上限,并且池中正在運行的線程數(shù)小于maximumPoolSize,對于新加入的任務(wù),新建線程。
下面用實驗來說明,代碼如下:
public classTestThreadPoolExecutor {public static voidmain(String[] args) {
ThreadPoolExecutor pool= new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));//任務(wù)1
pool.execute(newRunnable() {
@Overridepublic voidrun() {try{
Thread.sleep(3 * 1000);
System.out.println("-------------helloworld_001---------------" +Thread.currentThread().getName());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});//任務(wù)2
pool.execute(newRunnable() {
@Overridepublic voidrun() {try{
Thread.sleep(5 * 1000);
System.out.println("-------------helloworld_002---------------" +Thread.currentThread().getName());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});//任務(wù)3
pool.execute(newRunnable() {
@Overridepublic voidrun() {
System.out.println("-------------helloworld_003---------------" +Thread.currentThread().getName());
}
});//任務(wù)4
pool.execute(newRunnable() {
@Overridepublic voidrun() {
System.out.println("-------------helloworld_004---------------" +Thread.currentThread().getName());
}
});
}
}
實驗結(jié)果如下:
實驗結(jié)果分析:
當任務(wù)4進入隊列時發(fā)現(xiàn)隊列的長度已經(jīng)到了上限,所以無法進入隊列排隊,而此時正在運行的線程數(shù)(2)小于maximumPoolSize所以新建線程執(zhí)行該任務(wù)。
特性四:當隊列里的任務(wù)數(shù)達到上限,并且池中正在運行的線程數(shù)等于maximumPoolSize,對于新加入的任務(wù),執(zhí)行拒絕策略(線程池默認的拒絕策略是拋異常)。
下面用實驗來說明,代碼如下:
public classTestThreadPoolExecutor {public static voidmain(String[] args) {
ThreadPoolExecutor pool= new ThreadPoolExecutor(2, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));//任務(wù)1
pool.execute(newRunnable() {
@Overridepublic voidrun() {try{
Thread.sleep(3 * 1000);
System.out.println("-------------helloworld_001---------------" +Thread.currentThread().getName());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});//任務(wù)2
pool.execute(newRunnable() {
@Overridepublic voidrun() {try{
Thread.sleep(5 * 1000);
System.out.println("-------------helloworld_002---------------" +Thread.currentThread().getName());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
});//任務(wù)3
pool.execute(newRunnable() {
@Overridepublic voidrun() {
System.out.println("-------------helloworld_003---------------" +Thread.currentThread().getName());
}
});//任務(wù)4
pool.execute(newRunnable() {
@Overridepublic voidrun() {try{
Thread.sleep(2 * 1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("-------------helloworld_004---------------" +Thread.currentThread().getName());
}
});//任務(wù)5
pool.execute(newRunnable() {
@Overridepublic voidrun() {
System.out.println("-------------helloworld_005---------------" +Thread.currentThread().getName());
}
});
}
}
實驗結(jié)果如下:
實驗結(jié)果分析:
當任務(wù)5加入時,隊列達到上限,池內(nèi)運行的線程數(shù)達到最大,故執(zhí)行默認的拒絕策略,拋異常。
本文中使用到的隊列類型雖然僅限于LinkedBlockingQueue這一種隊列類型,但總結(jié)出來的特性,對與常用ArrayBlockingQueue 和?SynchronousQueue同樣適用,些許不同及三種隊列的區(qū)別,將在下個章節(jié)中說明。
最后說一點,我們作為程序員,研究問題還是要仔細深入一點的。當你對原理了解的有夠透徹,開發(fā)起來也就得心應(yīng)手了,很多開發(fā)中的問題和疑惑也就迎刃而解了,而且在面對其他問題的時候也可做到觸類旁通。當然在開發(fā)中沒有太多的時間讓你去研究原理,開發(fā)中要以實現(xiàn)功能為前提,可等項目上線的后,你有大把的時間或者空余的時間,你大可去刨根問底,深入的去研究一項技術(shù),為覺得這對一名程序員的成長是很重要的事情。
總結(jié)
以上是生活随笔為你收集整理的java new thread参数_java线程池01-ThreadPoolExecutor构造方法参数的使用规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: datagrip mysql乱码_Dat
- 下一篇: java volatile线程可见_vo