自定義線程池:簡單demo(+自定義ThreadFactory)實作
- 線程池作用簡述
-
- 一、上demo(自定義線程池)
- 二、ThreadFactory源碼簡述
-
- 1、方法定義
- 2、接口定義
線程池作用簡述
線程池主要作用是為了線程複用,避免線程頻繁建立。
線程池裡的線程是 ThreadFactory幫助建立的。
一、上demo(自定義線程池)
可以跟蹤線程池究竟在何時建立了多少線程,也可以自定義線程名稱,組,優先級,甚至直接設定所有線程為守護線程。可以通過自定義線程池更加自由的設定池子裡所有線程的狀态。下面案例一方面記錄線程的建立,另一方面把所有線程都設定為守護線程,當主線程退出後,将會強制銷毀線程池,省了我手動關閉線程池了,哈哈
package com.test.threadPoolStu;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.*;
/**自定義線程池*/
public class CustomizeThreadPool {
public static void main(String[] args) throws InterruptedException {
//自定義線程工廠 方式一:線程名稱揉入業務含義
// private static ThreadFactory customThreadFactory = new ThreadFactoryBuilder().setNameFormat("transAcount-pool-%d").build();
//自定義線程工廠 方式二
ThreadFactory customThreadFactory2=new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t=new Thread(r ); // Thread t=new Thread(r,"transAcount-pool-%d");
t.setName("transAcount-pool-"+t.getId());
t.setDaemon(true);//設定為守護線程
System.out.println("create "+t.getId()+": tName="+t.getName());
return t;
}
};
MyTask task=new MyTask();
ExecutorService es=new ThreadPoolExecutor(5,5,0L, TimeUnit.MILLISECONDS,
new SynchronousQueue<Runnable>(),customThreadFactory2);
for (int i=0;i<5;i++) {
es.submit(task);
}
Thread.sleep(2000);
}
public static class MyTask implements Runnable{
@Override
public void run(){
System.out.println(System.currentTimeMillis()+": Thread ID :"+Thread.currentThread().getId());
try {
Thread.sleep(100);
}catch (InterruptedException e){
System.out.println(e);
}
}
}
}
結果:能擷取到線程名稱,以及什麼時間建立的,而且任務輪訓完線程池關閉。
com.test.threadPoolStu.CustomizeThreadPool
create 11: tName=transAcount-pool-11
create 12: tName=transAcount-pool-12
create 13: tName=transAcount-pool-13
1597155474887: Thread ID :11
1597155474888: Thread ID :12
create 14: tName=transAcount-pool-14
1597155474889: Thread ID :13
create 15: tName=transAcount-pool-15
1597155474889: Thread ID :14
1597155474889: Thread ID :15
Process finished with exit code 0
自定義線程池 看到這就可以了,但如果你想了解ThreadFactory的源碼,可以繼續
二、ThreadFactory源碼簡述
ThreadFactory就一很樸素的接口,隻有一個方法newThread
看源碼能知道,具體可以參看下面的線程工廠源碼解讀
1、方法定義
1、怎麼使用?
①想用就實作這個接口,重寫建立線程的方法;
②或者你可以通過接口回調的形式重寫方法體。
使用的話,是放在ThreadPoolExecutor的構造裡作為一參數。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL1MGVOpXTE10MFpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLyUDO5ATOzIjMxEDOwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2、源碼的方法定義
方法定義上,至少咱能知道個大概。在你方法體裡,可以初始化線程優先級,指定名稱,甚至指定線程的狀态(直接指定為守候線程),設定組 .act
參數:通過執行runnable變量來執行個體化一個線程
傳回一個線程或者null.具體看你的内部實作哈!
當線程池需要建立線程的時候,就會調用這個方法;
一般自定義線程工廠的話,會指定線程名稱,這樣問題追溯起來也容易一些。
2、接口定義
1、 根據需要建立新線程的對象。使用線程工廠移除對new Thread(Runnable)(這種用法)調用的硬連線,應用程式可以使用特殊的線程子類,優先級等。
2、一個簡單的接口實作樣例:
class SimpleThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
return new Thread(r);
}
}
3、The {@link Executors#defaultThreadFactory} 示意這個連結提供了一個更有用的實作,建立的時候就設定線程的上下文(你點進去就是下圖了)