线程工厂(ThreadFactory接口)
在创建线程的时候,我们当然也能使用工厂模式来生产线程,ThreadFactory是用来实现创建线程的工厂接口,其实它只有一个方法Thread newThread(Runnable r),所以这个接口没多大用,可以自己编写新接口。
使用ThreadFactory工厂能替代默认的new Thread,而且在自定义工厂里面,我们能创建自定义化的Thread,并且计数,或则限制创建Thread的数量,给每个Thread设置对应的好听的名字,或则其他的很多很多事情。
An object that creates new threads on demand. Using thread factories removes hardwiring of calls to new Thread
, enabling applications to use special thread subclasses, priorities, etc.
The simplest implementation of this interface is just:
翻译过来就是:在需要的时候创建一个线程。使用线程工厂模式避免了new Thread的硬编码的方式创建线程,使得线程能自定义属性,后台,以及线程子类
JDK中默认的最简单的实现的方式就是(The simplest implementation of this interface is just:)
class SimpleThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { return new Thread(r); } }The
Executors.defaultThreadFactory
method provides a more useful simple implementation, that sets the created thread context to known values before returning it.
/** * The default thread factory */ static class DefaultThreadFactory implements ThreadFactory { static final AtomicInteger poolNumber = new AtomicInteger(1); final ThreadGroup group; final AtomicInteger threadNumber = new AtomicInteger(1); 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; } }
ThreadFactory在并发中的使用
在Java中使用ThreadFactory最多应该就是Executor框架和Fork/Join框架了,使用ThreadFactory创建各种线程池中的线程。在Executor框架中,使用Executors创建线程池执行器的时候,也可以传入ThreadFactory对象,执行器将会使用该ThreadFactory对象来创建线程。 如:newCachedThreadPool(ThreadFactory threadFactory)
下面的例子来自《Java并发编程实战》,展示一个简单的使用ThreadFactory来创建自己的Thread。工厂模式来创建自己的Thread。在创建线程的同时,记录线程创建的个数,并记录每个线程创建的时间等信息。
package MyThread; import java.util.concurrent.ThreadFactory; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; public 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(); } public static void main(String[] args) { MyThreadFactory factory = new MyThreadFactory("MyThreadFactory"); Task task = new Task(); Thread thread = null; for(int i = 0; i < 10; i++) { thread = factory.newThread(task); thread.start(); } System.out.printf("Factory stats:\n"); System.out.printf("%s\n",factory.getStas()); } } class Task implements Runnable{ @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }运行结果:
Factory stats:
Created thread 11 with name MyThreadFactory-Thread-0 onThu May 31 10:00:10 CST 2018
Created thread 12 with name MyThreadFactory-Thread-1 onThu May 31 10:00:10 CST 2018
Created thread 13 with name MyThreadFactory-Thread-2 onThu May 31 10:00:10 CST 2018
Created thread 14 with name MyThreadFactory-Thread-3 onThu May 31 10:00:10 CST 2018
Created thread 15 with name MyThreadFactory-Thread-4 onThu May 31 10:00:10 CST 2018
Created thread 16 with name MyThreadFactory-Thread-5 onThu May 31 10:00:10 CST 2018
Created thread 17 with name MyThreadFactory-Thread-6 onThu May 31 10:00:10 CST 2018
Created thread 18 with name MyThreadFactory-Thread-7 onThu May 31 10:00:10 CST 2018
Created thread 19 with name MyThreadFactory-Thread-8 onThu May 31 10:00:10 CST 2018
Created thread 20 with name MyThreadFactory-Thread-9 onThu May 31 10:00:10 CST 2018
第二个例子:
package com.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; class Task implements Runnable{ int taskId; public Task(int taskId) { this.taskId=taskId; } @Override public void run() { System.out.println(Thread.currentThread().getName()+"--taskId: "+taskId); } } class DaemonThreadFactory implements ThreadFactory { @Override public Thread newThread(Runnable r) { Thread t=new Thread(r); t.setDaemon(true); return t; } } public class ThreadFactoryTest { public static void main(String[] args) { ExecutorService exec=Executors.newFixedThreadPool(3,new DaemonThreadFactory()); for(int i=0;i<3;i++) { exec.submit(new Task(i)); } exec.shutdown(); } }