004-多线程-JUC线程池-ThreadFactory线程工厂
一、源码分析
ThreadFactory是一个线程工厂。用来创建线程。这里为什么要使用线程工厂呢?其实就是为了统一在创建线程时设置一些参数,如是否守护线程。线程一些特性等,如优先级。通过这个TreadFactory创建出来的线程能保证有相同的特性。它首先是一个接口类,而且方法只有一个。就是创建一个线程。
public interface ThreadFactory { Thread newThread(Runnable r); }
1》ThreadPoolExecutor创建
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
最终均会调用创建以下构造方法
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
2》查看 Executors.defaultThreadFactory()实现
public static ThreadFactory defaultThreadFactory() { return new DefaultThreadFactory(); }
在JDK中,有实现ThreadFactory就只有一个地方。而更多的时候,我们都是继承它然后自己来写这个线程工厂的。
下面的代码中在类Executors当中。默认的 我们创建线程池时使用的就是这个线程工厂
static class DefaultThreadFactory implements ThreadFactory { private static final AtomicInteger poolNumber = new AtomicInteger(1);//原子类,线程池编号 private final ThreadGroup group;//线程组 private final AtomicInteger threadNumber = new AtomicInteger(1);//线程数目 private final String namePrefix;//为每个创建的线程添加的前缀 DefaultThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();//取得线程组 namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; } public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);//真正创建线程的地方,设置了线程的线程组及线程名 if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY)//默认是正常优先级 t.setPriority(Thread.NORM_PRIORITY); return t; } }
在上面的代码中,可以看到线程池中默认的线程工厂实现是很简单的,它做的事就是统一给线程池中的线程设置线程group、统一的线程前缀名。以及统一的优先级。
2、以下是自己实现ThreadFactory示例
package com.func.axc.threadfactory; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.concurrent.ThreadFactory; /** */ public class ThreadFactoryTest { static class MyThreadFactory implements ThreadFactory { private int counter; private String name; private List<String> stats; public MyThreadFactory(String name) { counter = 0; this.name = name; stats = new ArrayList<String>(); } @Override public Thread newThread(Runnable run) { Thread t = new Thread(run, name + "-Thread-" + counter); counter++; stats.add(String.format("Created thread %d with name %s on%s\n",t.getId(), t.getName(), new Date())); return t; } public String getStas() { StringBuffer buffer = new StringBuffer(); Iterator<String> it = stats.iterator(); while (it.hasNext()) { buffer.append(it.next()); buffer.append("\n"); } return buffer.toString(); } } static class MyTask implements Runnable { private int num; public MyTask(int num) { this.num = num; } @Override public void run() { System.out.println("Task "+ num+" is running"); try { Thread.sleep(2*10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { System.out.println("main thread beging"); MyThreadFactory factory = new MyThreadFactory("MyThreadFactory"); Thread thread = null; for(int i = 0; i < 10; i++) { thread = factory.newThread(new MyTask(i)); thread.start(); } System.out.printf("Factory stats:\n"); System.out.printf("%s\n",factory.getStas()); System.out.println("main thread end"); } }