一、源码分析

  ThreadFactory是一个线程工厂。用来创建线程。这里为什么要使用线程工厂呢?其实就是为了统一在创建线程时设置一些参数,如是否守护线程。线程一些特性等,如优先级。通过这个TreadFactory创建出来的线程能保证有相同的特性。它首先是一个接口类,而且方法只有一个。就是创建一个线程。

  1. public interface ThreadFactory {
  2. Thread newThread(Runnable r);
  3. }

1》ThreadPoolExecutor创建

  1. public ThreadPoolExecutor(int corePoolSize,
  2. int maximumPoolSize,
  3. long keepAliveTime,
  4. TimeUnit unit,
  5. BlockingQueue<Runnable> workQueue) {
  6. this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
  7. Executors.defaultThreadFactory(), defaultHandler);
  8. }

最终均会调用创建以下构造方法

  1. public ThreadPoolExecutor(int corePoolSize,
  2. int maximumPoolSize,
  3. long keepAliveTime,
  4. TimeUnit unit,
  5. BlockingQueue<Runnable> workQueue,
  6. ThreadFactory threadFactory,
  7. RejectedExecutionHandler handler) {
  8. if (corePoolSize < 0 ||
  9. maximumPoolSize <= 0 ||
  10. maximumPoolSize < corePoolSize ||
  11. keepAliveTime < 0)
  12. throw new IllegalArgumentException();
  13. if (workQueue == null || threadFactory == null || handler == null)
  14. throw new NullPointerException();
  15. this.acc = System.getSecurityManager() == null ?
  16. null :
  17. AccessController.getContext();
  18. this.corePoolSize = corePoolSize;
  19. this.maximumPoolSize = maximumPoolSize;
  20. this.workQueue = workQueue;
  21. this.keepAliveTime = unit.toNanos(keepAliveTime);
  22. this.threadFactory = threadFactory;
  23. this.handler = handler;
  24. }

2》查看 Executors.defaultThreadFactory()实现

  1. public static ThreadFactory defaultThreadFactory() {
  2. return new DefaultThreadFactory();
  3. }

  在JDK中,有实现ThreadFactory就只有一个地方。而更多的时候,我们都是继承它然后自己来写这个线程工厂的。

  下面的代码中在类Executors当中。默认的 我们创建线程池时使用的就是这个线程工厂

  1. static class DefaultThreadFactory implements ThreadFactory {
  2. private static final AtomicInteger poolNumber = new AtomicInteger(1);//原子类,线程池编号
  3. private final ThreadGroup group;//线程组
  4. private final AtomicInteger threadNumber = new AtomicInteger(1);//线程数目
  5. private final String namePrefix;//为每个创建的线程添加的前缀
  6.  
  7. DefaultThreadFactory() {
  8. SecurityManager s = System.getSecurityManager();
  9. group = (s != null) ? s.getThreadGroup() :
  10. Thread.currentThread().getThreadGroup();//取得线程组
  11. namePrefix = "pool-" +
  12. poolNumber.getAndIncrement() +
  13. "-thread-";
  14. }
  15.  
  16. public Thread newThread(Runnable r) {
  17. Thread t = new Thread(group, r,
  18. namePrefix + threadNumber.getAndIncrement(),
  19. 0);//真正创建线程的地方,设置了线程的线程组及线程名
  20. if (t.isDaemon())
  21. t.setDaemon(false);
  22. if (t.getPriority() != Thread.NORM_PRIORITY)//默认是正常优先级
  23. t.setPriority(Thread.NORM_PRIORITY);
  24. return t;
  25. }
  26. }

  在上面的代码中,可以看到线程池中默认的线程工厂实现是很简单的,它做的事就是统一给线程池中的线程设置线程group、统一的线程前缀名。以及统一的优先级。

2、以下是自己实现ThreadFactory示例

  1. package com.func.axc.threadfactory;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Date;
  5. import java.util.Iterator;
  6. import java.util.List;
  7. import java.util.concurrent.ThreadFactory;
  8.  
  9. /**
  10. */
  11. public class ThreadFactoryTest {
  12.  
  13. static class MyThreadFactory implements ThreadFactory {
  14.  
  15. private int counter;
  16. private String name;
  17. private List<String> stats;
  18.  
  19. public MyThreadFactory(String name) {
  20. counter = 0;
  21. this.name = name;
  22. stats = new ArrayList<String>();
  23. }
  24.  
  25. @Override
  26. public Thread newThread(Runnable run) {
  27. Thread t = new Thread(run, name + "-Thread-" + counter);
  28. counter++;
  29. stats.add(String.format("Created thread %d with name %s on%s\n",t.getId(), t.getName(), new Date()));
  30. return t;
  31. }
  32.  
  33. public String getStas() {
  34. StringBuffer buffer = new StringBuffer();
  35. Iterator<String> it = stats.iterator();
  36. while (it.hasNext()) {
  37. buffer.append(it.next());
  38. buffer.append("\n");
  39. }
  40. return buffer.toString();
  41. }
  42.  
  43. }
  44.  
  45. static class MyTask implements Runnable {
  46.  
  47. private int num;
  48.  
  49. public MyTask(int num) {
  50. this.num = num;
  51. }
  52.  
  53. @Override
  54. public void run() {
  55. System.out.println("Task "+ num+" is running");
  56. try {
  57. Thread.sleep(2*10000);
  58. } catch (InterruptedException e) {
  59. // TODO Auto-generated catch block
  60. e.printStackTrace();
  61. }
  62.  
  63. }
  64.  
  65. }
  66.  
  67. public static void main(String[] args) {
  68. System.out.println("main thread beging");
  69. MyThreadFactory factory = new MyThreadFactory("MyThreadFactory");
  70.  
  71. Thread thread = null;
  72. for(int i = 0; i < 10; i++) {
  73. thread = factory.newThread(new MyTask(i));
  74. thread.start();
  75. }
  76. System.out.printf("Factory stats:\n");
  77. System.out.printf("%s\n",factory.getStas());
  78. System.out.println("main thread end");
  79. }
  80.  
  81. }

011-ThreadFactory线程工厂的更多相关文章

  1. JUC——ThreadFactory线程工厂类(四)

    ThreadFactory线程工厂类 在默认情况下如果要想创建一个线程类对象,大部分情况的选择是:直接通过子类为父类进行实例化,利用Runnable子类为Runnable接口实例化. 或者直接调用La ...

  2. JAVA并发,线程工厂及自定义线程池

    package com.xt.thinks21_2; import java.util.concurrent.ExecutorService; import java.util.concurrent. ...

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

    目录 引言 四种线程池 newCachedThreadPool:可缓存的线程池 newFixedThreadPool:定长线程池 newSingleThreadExecutor:单线程线程池 newS ...

  4. Java利用线程工厂监控线程池

    目录 ThreadFactory 监控线程池 扩展线程池 扩展线程池示例 优化线程池大小 线程池死锁 线程池异常信息捕获 ThreadFactory 线程池中的线程从哪里来呢?就是ThreadFoct ...

  5. Java Concurrency - ThreadFactory, 使用工厂方法创建线程

    当需要创建多个类似的线程实例时,使用工厂模式替代 new 操作符创建线程,能使代码更为简洁,易于维护.JDK 提供了 java.util.concurrent.ThreadFactory 接口,Thr ...

  6. 【Thread】线程工厂-ThreadFactory

    ThreadFactory---线程工厂 在apollo源码中有这么一段代码 ExecutorService m_longPollingService = Executors.newSingleThr ...

  7. ThreadFactory 线程池工厂

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Thr ...

  8. Java线程池应用及原理分析(JDK1.8)

    目录 一.线程池优点 二.线程池创建 三.任务处理流程 四.任务缓存队列及排队策略 五.任务拒绝策略 六.线程池关闭 七.线程池实现原理 八.静态方法创建线程池 九.如何确定线程池大小 一.线程池优点 ...

  9. 深入理解java线程池—ThreadPoolExecutor

    几句闲扯:首先,我想说java的线程池真的是很绕,以前一直都感觉新建几个线程一直不退出到底是怎么实现的,也就有了后来学习ThreadPoolExecutor源码.学习源码的过程中,最恶心的其实就是几种 ...

随机推荐

  1. [CNN] Tool - Deep Visualization

    From: http://www.infoq.com/cn/news/2016/12/depth-neural-network-fake-photos 当时大部分的DNN在识别图像中对象的过程中主要依 ...

  2. [PHP] 03 - Form & Input

    PHP 完整表单实例 一.表单示范 二.对应代码 <!DOCTYPE HTML> <html> <head> <meta charset="utf- ...

  3. Python实现C代码统计工具(三)

    目录 Python实现C代码统计工具(三) 声明 一. 性能分析 1.1 分析单条语句 1.2 分析代码片段 1.3 分析整个模块 二. 制作exe Python实现C代码统计工具(三) 标签: Py ...

  4. vue使用render渲染&jsx

    vue&jsx文档 vue实例属性 // App.ts import hBtn from './components/hBtn' import hUl from './components/h ...

  5. db2 查杀死锁进程

    db2 查杀死锁进命令 db2 get snapshot for locks on (需要snapshot的访问权限) db2 list applications db2 "force ap ...

  6. DB2 Version 10.5 补丁下载

    DB2 Version 10.5 for Linux, UNIX, and Windows fix pack summary https://www.ibm.com/support/knowledge ...

  7. SQL 2017 远程连接被拒绝

    1.防火墙端口 2.数据库要能帐号登录 可是还是不行 打开:SQL Server 2017 配置管理器->SQL Server 服务 ->SQLServer(你的实例名)-> 右键- ...

  8. 文件下载报错:引发类型为“System.OutOfMemoryException”的异常-.Net 内存溢出

    CSDN:http://blog.csdn.net/huwei2003/article/details/53559272 设置了也没有用,于是想到手动清理应用程序池,但又迁配置问题于是改成最后的方式! ...

  9. [No000013A]Windows WMIC命令使用详解(附实例)

    第一次执行WMIC命令时,Windows首先要安装WMIC,然后显示出WMIC的命令行提示符.在WMIC命令行提示符上,命令以交互的方式执行 执行“wmic”命令启动WMIC命令行环境.这个命令可以在 ...

  10. [No000011A]Office Excel设置显示日期与星期

    设置excel日期格式,自定义,yyyy-mm-dd 上午/下午 hh:mm:ss AM/PM dddd aaaa