1、Java中的线程池
java API提供了三种线程池Executors.newCachedThreadPool(),Executors.newFixedThreadPool(.),Executors.newSingleThreadExecutor(),一般情况下我们都可以使用这里定义的线程池来完成我们的任务。
2、定制线程池
查看Executors.newCachedThreadPool()的源代码我们可以知道,通过自己new ThreadPoolExecutor我们可以通过传入不同的参数来定制自己的线程池。
代码一:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
上面的代码还有一个重载方法,除了接受上面例子中的参数外,还可以额外接受一个ThreadFactory threadFactory参数。
代码二:
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
从代码一我们知道,通过自己new ThreadPoolExecutor可以定制线程池的属性。
从代码二我们知道,通过实现自己的ThreadFactory我们可以定制产生线程的方式。
下面我们实现一个总是产生后台线程的线程池
class MyExecutors
{
/**
* 设置线程池的属性,并且传入我们自己的线程工厂
*/
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
120L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
}
/**
* 创建线程的工厂,设置线程的属性
*/
class MyThreadFactory implements ThreadFactory
{
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
t.setPriority(Thread.MAX_PRIORITY);
return t;
}
}
class TaskTest implements Runnable
{
@Override
public void run() {
System.out.println(Thread.currentThread().isDaemon());
}
}
public class ThreadPoolTest
{
public static void main(String[] args)
{
ExecutorService exec = MyExecutors.newCachedThreadPool(new MyThreadFactory());
exec.execute(new TaskTest());
exec.shutdown();
}
}
上述程序会在控制台输出true,表明我们成功定制了线程池生产出来的线程的属性。