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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

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

引言

通過前面的文章,我們學習了Executor框架中的核心類ThreadPoolExecutor ,對于線程池的核心調度機制有了一定的了解,并且成功使用ThreadPoolExecutor 創建了線程池。

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

四種線程池

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

newCachedThreadPool:可緩存的線程池

源碼:

public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

newCachedThreadPool的方法中是返回一個ThreadPoolExecutor實例,從源碼中可以看出該線程池的特點:

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

2、創建ThreadPoolExecutor實例時傳過去的參數是一個SynchronousQueue實例,說明在創建任務時,若存在空閑線程就復用它,沒有的話再新建線程。

3、線程處于閑置狀態超過60s的話,就會被銷毀。

用法:

public static void main(String[] args) {

//定義ExecutorService實例

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();

}

//調用execute方法

cachedThreadPool.execute(new Runnable() {

@Override

public void run() {

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

}

});

}

}

上面的代碼因為每次循環都是隔一秒執行,這個時間足夠之前的線程工作完畢,并在新循環中復用這個線程,程序的運行結果如下:

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:定長線程池

源碼:

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

}

線程池特點:

1、線程池的最大線程數等于核心線程數,并且線程池的線程不會因為閑置超時被銷毀。

2、使用的列隊是LinkedBlockingQueue,表示如果當前線程數小于核心線程數,那么即使有空閑線程也不會復用線程去執行任務,而是創建新的線程去執行任務。如果當前執行任務數量大于核心線程數,此時再提交任務就在隊列中等待,直到有可用線程。

用法:

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);

}

});

}

}

定義一個線程數為3的線程池,循環10次執行,可以發現運行的線程永遠只有三個,結果如下:

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()));

}

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

用法:

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

newScheduledThreadPool:支持定時的定長線程池

源碼:

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的方法不是直接返回一個ThreadPoolExecutor實例,而是通過有定時功能的ThreadPoolExecutor,也就是ScheduledThreadPoolExecutor 來返回ThreadPoolExecutor實例,從源碼中可以看出:

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

2、該線程池采用的隊列是DelayedWorkQueue,具有延遲和定時的作用。

用法:

public static void main(String[] args) {

ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

//延遲3秒執行,只執行一次

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

@Override

public void run() {

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

}

},3,TimeUnit.SECONDS);

//延遲1秒后每隔兩秒執行一次

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

@Override

public void run() {

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

}

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

}

自定義ThreadFactory

四種線程池的使用就說到這里了,值得說明的是,除了上面的參數外,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是一個接口類,也就是我們經常說的線程工廠,只有一個方法,可以用于創建線程:

Thread newThread(Runnable r);

默認情況下,ThreadPoolExecutor構造器傳入的ThreadFactory 參數是Executors類中的defaultThreadFactory(),相當于一個線程工廠,幫我們創建了線程池中所需的線程。

除此之外,我們也可以自定義ThreadFactory,并根據自己的需要來操作線程,下面是實例代碼:

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表達式編寫方法體中的邏輯

Runnable run = () -> {

try {

Thread.sleep(1000);

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

} catch (InterruptedException e) {

e.printStackTrace();

}

};

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

service.submit(run);

}

//這里一定要做關閉

service.shutdown();

}

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。