天天看點

自定義線程池:簡單demo(+自定義ThreadFactory)實作線程池作用簡述

自定義線程池:簡單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的構造裡作為一參數。

自定義線程池:簡單demo(+自定義ThreadFactory)實作線程池作用簡述

2、源碼的方法定義

方法定義上,至少咱能知道個大概。在你方法體裡,可以初始化線程優先級,指定名稱,甚至指定線程的狀态(直接指定為守候線程),設定組 .act

參數:通過執行runnable變量來執行個體化一個線程

傳回一個線程或者null.具體看你的内部實作哈!

當線程池需要建立線程的時候,就會調用這個方法;

一般自定義線程工廠的話,會指定線程名稱,這樣問題追溯起來也容易一些。

自定義線程池:簡單demo(+自定義ThreadFactory)實作線程池作用簡述

2、接口定義

自定義線程池:簡單demo(+自定義ThreadFactory)實作線程池作用簡述

1、 根據需要建立新線程的對象。使用線程工廠移除對new Thread(Runnable)(這種用法)調用的硬連線,應用程式可以使用特殊的線程子類,優先級等。

2、一個簡單的接口實作樣例:

class SimpleThreadFactory implements ThreadFactory {
     public Thread newThread(Runnable r) {
       return new Thread(r);
    }
   }
           

3、The {@link Executors#defaultThreadFactory} 示意這個連結提供了一個更有用的實作,建立的時候就設定線程的上下文(你點進去就是下圖了)

自定義線程池:簡單demo(+自定義ThreadFactory)實作線程池作用簡述