暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

并发编程 | 使用ThreadFactory初始化线程池

尹洪亮Kevin 2021-07-30
3247

 使用ThreadFactory可以控制线程池内,线程创建前的行为


01

说明


全路径java.util.concurrent.ThreadFactory

是一个接口,内部只声明了一个newThread方法

接口声明如下

    public interface ThreadFactory {
    Thread newThread(Runnable r);
    }



    02


    原理


    我们通常使用线程池的submit方法将任务提交到线程池内执行。


    如果此时线程池内有空闲的线程,则会立即执行该任务,如果没有则需要根据线程池的类型选择等待,或者新建线程。


    所以线程池内的线程并不是线程池对象初始化(new)的时候就创建好的。而是当有任务被提交进来之后才创建的,而创建线程的过程是无法干预的。


    如果我们想在每个线程创建时记录一些日志,或者推送一些消息那怎么做?


    就可以使用ThreadFactory来达到目的,让线程池内的每个线程都通过ThreadFactory来创建。



    02


    使用案例


    使用ThreadFactory十分简单

    第一步: 编写ThreadFactory接口的实现类

    第二步: 创建线程池时传入ThreadFactory对象


    案例:希望在线程创建的时候输出日志,并且给每个线程起一个自己的名字


    (提醒:代码可复制粘贴直接运行)


    第一步:编写ThreadFactory接口的实现类

    (代码较大请横向滑动或使用PC查看

      import java.util.concurrent.ThreadFactory;
      import java.util.concurrent.ThreadLocalRandom;
      /**
      * 线程工场
      */
      class DemoThreadFactory implements ThreadFactory {




      是否记录日志,true输出日志,false不输出日志
      private boolean saveLog;
      工场名称
      private String factoryName;




      public DemoThreadFactory(String factoryName, boolean saveLog) {
      this.factoryName = factoryName;
      this.saveLog = saveLog;
      }




      public Thread newThread(Runnable r) {
      if (saveLog) {
      动态输出日志
      System.out.println(System.currentTimeMillis() + this.factoryName + " create start");
      }
      Thread thread = new Thread(r);
      自定义线程名字
      thread.setName("Kevin-Thread-" + thread.getName() + ":" + thread.getId());
      try {
      模拟初始化时间
      Thread.sleep(ThreadLocalRandom.current().nextInt(1000));
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      if (saveLog) {
      System.out.println(System.currentTimeMillis() + this.factoryName + " " + thread.getName() + " create end");
      }
      return thread;
      }
      }


      第二步:创建线程池时传入ThreadFactory对象


      (代码较大请横向滑动或使用PC查看)

        /**
        * 使用线程工场创建线程
        */
        public class ThreadFactoryDemo0 {
        public static void main(String[] args) {




        //创建任务对象
        Runnable runnable = new Runnable() {
        public void run() {
        System.out.println(Thread.currentThread().getName() + " run");
        }
        };




        System.out.println("newCachedThreadPool使用ThreadFactory");
        //创建自定义线程工场
        DemoThreadFactory threadFactory = new DemoThreadFactory("newCachedThreadPoolFactory",true);
        //使用线程工场初始化线程池
        ExecutorService executorService = Executors.newCachedThreadPool(threadFactory);
        for (int i = 0; i < 3; i++) {
        executorService.execute(runnable);
        }
        executorService.shutdown();


        System.out.println("newFixedThreadPool使用ThreadFactory");
        //创建自定义线程工场
        threadFactory = new DemoThreadFactory("newFixedThreadPoolFactory",true);
        //使用线程工场初始化线程池
        executorService = Executors.newFixedThreadPool(2, threadFactory);
        for(int i=0;i<3;i++){
        executorService.execute(runnable);
        }
        executorService.shutdown();


        //创建其他线程池也可以使用ThreadFactory
        //Executors.newScheduledThreadPool(2,threadFactory);
        //Executors.newSingleThreadExecutor(threadFactory);
        //Executors.newSingleThreadScheduledExecutor(threadFactory);
        }
        }

        运行结果

          ---------------------------------------------
          newCachedThreadPool使用ThreadFactory
          ---------------------------------------------
          1573661399611newCachedThreadPoolFactory create start
          1573661400155newCachedThreadPoolFactory Kevin-Thread-Thread-0:11 create end
          1573661400155newCachedThreadPoolFactory create start
          Kevin-Thread-Thread-0:11 run
          1573661400755newCachedThreadPoolFactory Kevin-Thread-Thread-1:12 create end
          ---------------------------------------------
          newFixedThreadPool使用ThreadFactory
          ---------------------------------------------
          1573661400756newFixedThreadPoolFactory create start
          Kevin-Thread-Thread-0:11 run
          Kevin-Thread-Thread-1:12 run
          1573661401042newFixedThreadPoolFactory Kevin-Thread-Thread-2:13 create end
          1573661401043newFixedThreadPoolFactory create start
          Kevin-Thread-Thread-2:13 run
          1573661401445newFixedThreadPoolFactory Kevin-Thread-Thread-3:14 create end
          Kevin-Thread-Thread-3:14 run
          Kevin-Thread-Thread-2:13 run


          想快速精通并发编程,点击公众下方的“阅读原文” 学习由Kevin本人录制的《JAVA并发编程-豪华版》课程。

          阅读原文了解我课程 。和朋友一起在看

          文章转载自尹洪亮Kevin,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论