日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂

發(fā)布時(shí)間:2023/12/9 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

引言

通過(guò)前面的文章,我們學(xué)習(xí)了Executor框架中的核心類ThreadPoolExecutor ,對(duì)于線程池的核心調(diào)度機(jī)制有了一定的了解,并且成功使用ThreadPoolExecutor 創(chuàng)建了線程池。

而在Java中,除了ThreadPoolExecutor ,Executor框架中還提供了四種線程池,這四種線程池都是直接或間接配置ThreadPoolExecutor的參數(shù)實(shí)現(xiàn)的,對(duì)于ThreadPoolExecutor類不熟悉的讀者可以參考Java并發(fā)編程:Java線程池核心ThreadPoolExecutor的使用和原理分析

四種線程池

四種線程池分別是:newCachedThreadPool、newFixedThreadPool 、newScheduledThreadPool 和newSingleThreadExecutor ,下面對(duì)這幾個(gè)線程池一一講解。

newCachedThreadPool:可緩存的線程池

源碼:

public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

newCachedThreadPool的方法中是返回一個(gè)ThreadPoolExecutor實(shí)例,從源碼中可以看出該線程池的特點(diǎn):

1、該線程池的核心線程數(shù)量是0,線程的數(shù)量最高可以達(dá)到Integer 類型最大值;

2、創(chuàng)建ThreadPoolExecutor實(shí)例時(shí)傳過(guò)去的參數(shù)是一個(gè)SynchronousQueue實(shí)例,說(shuō)明在創(chuàng)建任務(wù)時(shí),若存在空閑線程就復(fù)用它,沒(méi)有的話再新建線程。

3、線程處于閑置狀態(tài)超過(guò)60s的話,就會(huì)被銷毀。

用法:

public static void main(String[] args) {

//定義ExecutorService實(shí)例

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

for (int i = 0; i < 10; i++) {

final int index = i;

try {

Thread.sleep(index * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

//調(diào)用execute方法

cachedThreadPool.execute(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread() + ":" + index);

}

});

}

}

上面的代碼因?yàn)槊看窝h(huán)都是隔一秒執(zhí)行,這個(gè)時(shí)間足夠之前的線程工作完畢,并在新循環(huán)中復(fù)用這個(gè)線程,程序的運(yùn)行結(jié)果如下:

Thread[pool-1-thread-1,5,main]:0

Thread[pool-1-thread-1,5,main]:1

Thread[pool-1-thread-1,5,main]:2

Thread[pool-1-thread-1,5,main]:3

Thread[pool-1-thread-1,5,main]:4

Thread[pool-1-thread-1,5,main]:5

Thread[pool-1-thread-1,5,main]:6

Thread[pool-1-thread-1,5,main]:7

Thread[pool-1-thread-1,5,main]:8

Thread[pool-1-thread-1,5,main]:9

newFixedThreadPool:定長(zhǎng)線程池

源碼:

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

}

線程池特點(diǎn):

1、線程池的最大線程數(shù)等于核心線程數(shù),并且線程池的線程不會(huì)因?yàn)殚e置超時(shí)被銷毀。

2、使用的列隊(duì)是LinkedBlockingQueue,表示如果當(dāng)前線程數(shù)小于核心線程數(shù),那么即使有空閑線程也不會(huì)復(fù)用線程去執(zhí)行任務(wù),而是創(chuàng)建新的線程去執(zhí)行任務(wù)。如果當(dāng)前執(zhí)行任務(wù)數(shù)量大于核心線程數(shù),此時(shí)再提交任務(wù)就在隊(duì)列中等待,直到有可用線程。

用法:

public static void main(String[] args) {

ExecutorService cachedThreadPool = Executors.newFixedThreadPool(3);

for (int i = 0; i < 10; i++) {

final int index = i;

try {

Thread.sleep(index * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

cachedThreadPool.execute(new Runnable() {

@Override

public void run() {

System.out.println(Thread.currentThread() + ":" + index);

}

});

}

}

定義一個(gè)線程數(shù)為3的線程池,循環(huán)10次執(zhí)行,可以發(fā)現(xiàn)運(yùn)行的線程永遠(yuǎn)只有三個(gè),結(jié)果如下:

Thread[pool-1-thread-1,5,main]:0

Thread[pool-1-thread-2,5,main]:1

Thread[pool-1-thread-3,5,main]:2

Thread[pool-1-thread-1,5,main]:3

Thread[pool-1-thread-2,5,main]:4

Thread[pool-1-thread-3,5,main]:5

Thread[pool-1-thread-1,5,main]:6

Thread[pool-1-thread-2,5,main]:7

Thread[pool-1-thread-3,5,main]:8

Thread[pool-1-thread-1,5,main]:9

newSingleThreadExecutor:單線程線程池

源碼:

public static ExecutorService newSingleThreadExecutor() {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue()));

}

從源碼就可以看出,該線程池基本就是只有一個(gè)線程數(shù)的newFixedThreadPool,它只有一個(gè)線程在工作,所有任務(wù)按照指定順序執(zhí)行。

用法:

和newFixedThreadPool類似,只是一直只有一個(gè)線程在工作,這里就不貼代碼了。

newScheduledThreadPool:支持定時(shí)的定長(zhǎng)線程池

源碼:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {

return new ScheduledThreadPoolExecutor(corePoolSize);

}

public ScheduledThreadPoolExecutor(int corePoolSize) {

super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,

new DelayedWorkQueue());

}

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), defaultHandler);

}

newScheduledThreadPool的方法不是直接返回一個(gè)ThreadPoolExecutor實(shí)例,而是通過(guò)有定時(shí)功能的ThreadPoolExecutor,也就是ScheduledThreadPoolExecutor 來(lái)返回ThreadPoolExecutor實(shí)例,從源碼中可以看出:

1、該線程池可以設(shè)置核心線程數(shù)量,最大線程數(shù)與newCachedThreadPool一樣,都是Integer.MAX_VALUE。

2、該線程池采用的隊(duì)列是DelayedWorkQueue,具有延遲和定時(shí)的作用。

用法:

public static void main(String[] args) {

ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

//延遲3秒執(zhí)行,只執(zhí)行一次

((ScheduledExecutorService) scheduledThreadPool).schedule(new Runnable() {

@Override

public void run() {

System.out.println("延遲========");

}

},3,TimeUnit.SECONDS);

//延遲1秒后每隔兩秒執(zhí)行一次

((ScheduledExecutorService) scheduledThreadPool).scheduleAtFixedRate(new Runnable() {

@Override

public void run() {

System.out.println("執(zhí)行============");

}

},1,2,TimeUnit.SECONDS); //單位是秒

}

自定義ThreadFactory

四種線程池的使用就說(shuō)到這里了,值得說(shuō)明的是,除了上面的參數(shù)外,Executors類中還給這四種線程池提供了可傳ThreadFactory的重載方法,以下是它們的源碼:

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue(),

threadFactory));

}

public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue(),

threadFactory);

}

public static ScheduledExecutorService newScheduledThreadPool(

int corePoolSize, ThreadFactory threadFactory) {

return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);

}

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue(),

threadFactory);

}

ThreadFactory是一個(gè)接口類,也就是我們經(jīng)常說(shuō)的線程工廠,只有一個(gè)方法,可以用于創(chuàng)建線程:

Thread newThread(Runnable r);

默認(rèn)情況下,ThreadPoolExecutor構(gòu)造器傳入的ThreadFactory 參數(shù)是Executors類中的defaultThreadFactory(),相當(dāng)于一個(gè)線程工廠,幫我們創(chuàng)建了線程池中所需的線程。

除此之外,我們也可以自定義ThreadFactory,并根據(jù)自己的需要來(lái)操作線程,下面是實(shí)例代碼:

public static void main(String[] args) {

ExecutorService service = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS,

new SynchronousQueue(), new ThreadFactory() {

@Override

public Thread newThread(Runnable r) {

Thread t = new Thread(r);

System.out.println("我是線程" + r);

return t;

}

}

);

//用lambda表達(dá)式編寫(xiě)方法體中的邏輯

Runnable run = () -> {

try {

Thread.sleep(1000);

System.out.println(Thread.currentThread().getName() + "正在執(zhí)行");

} catch (InterruptedException e) {

e.printStackTrace();

}

};

for (int i = 0; i < 5; i++) {

service.submit(run);

}

//這里一定要做關(guān)閉

service.shutdown();

}

運(yùn)行代碼后,控制行會(huì)輸出五行 “我是線程java.util.concurrent.ThreadPoolExecutor。。。。。”的信息,也證明了我們自定義的ThreadFactory起到了作用。

總結(jié)

以上是生活随笔為你收集整理的java 线程工厂_Java并发编程:Java的四种线程池的使用,以及自定义线程工厂的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。