Java并发编程中使用Executors类创建和管理线程的用法
1.类Executors
Executors类可以看做一个“工具类”。援引JDK1.6API中的介绍:
此包中所定义的Executor、ExecutorService、ScheduledExecutorService、ThreadFactory和Callable类的工厂和实用方法。此类支持以下各种方法:
(1)创建并返回设置有常用配置字符串的ExecutorService的方法。
(2)创建并返回设置有常用配置字符串的ScheduledExecutorService的方法。
(3)创建并返回“包装的”ExecutorService方法,它通过使特定于实现的方法不可访问来禁用重新配置。
(4)创建并返回ThreadFactory的方法,它可将新创建的线程设置为已知的状态。
(5)创建并返回非闭包形式的Callable的方法,这样可将其用于需要Callable的执行方法中。
通过这个类能够获得多种线程池的实例,例如可以调用newSingleThreadExecutor()获得单线程的ExecutorService,调用newFixedThreadPool()获得固定大小线程池的ExecutorService,等等。拿到ExecutorService可以做的事情就比较多了,最简单的是用它来执行Runnable对象,也可以执行一些实现了Callable<T>的对象。用Thread的start()方法没有返回值,如果该线程执行的方法有返回值那用ExecutorService就再好不过了,可以选择submit()、invokeAll()或者invokeAny(),根据具体情况选择合适的方法即可。
此类中提供的一些方法有:
1.1publicstaticExecutorServicenewCachedThreadPool()
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。
1.2publicstaticExecutorServicenewFixedThreadPool(intnThreads)
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
1.3publicstaticExecutorServicenewSingleThreadExecutor()
创建一个使用单个worker线程的Executor,以无界队列方式来运行该线程。
这三个方法都可以配合接口ThreadFactory的实例一起使用。并且返回一个ExecutorService接口的实例。
2.接口ThreadFactory
根据需要创建新线程的对象。使用线程工厂就无需再手工编写对newThread的调用了,从而允许应用程序使用特殊的线程子类、属性等等。
此接口最简单的实现就是:
classSimpleThreadFactoryimplementsThreadFactory{
publicThreadnewThread(Runnabler){
returnnewThread(r);
}
}
3.接口ExecutorService
该接口提供了管理终止的方法。
4.创建标准线程池启动线程
4.1提供一个简单的实现Runnable接口的线程
MyThread.java
packagecom.zj.concurrency.executors;
publicclassMyThreadimplementsRunnable{
privateintcount=1,number;
publicMyThread(intnum){
number=num;
System.out.println("CreateThread-"+number);
}
publicvoidrun(){
while(true){
System.out.println("Thread-"+number+"run"+count+"time(s)");
if(++count==3)
return;
}
}
}
这个线程会打印出相应的创建和执行信息。
4.2使用CachedThreadPool启动线程
CachedThreadPool.java
packagecom.zj.concurrency.executors;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
publicclassCachedThreadPool{
publicstaticvoidmain(String[]args){
ExecutorServiceexec=Executors.newCachedThreadPool();
for(inti=0;i<5;i++)
exec.execute(newMyThread(i));
exec.shutdown();
}
}
结果:
CreateThread-0 CreateThread-1 CreateThread-2 CreateThread-3 Thread-0run1time(s) Thread-0run2time(s) Thread-1run1time(s) Thread-1run2time(s) Thread-2run1time(s) Thread-2run2time(s) CreateThread-4 Thread-4run1time(s) Thread-4run2time(s) Thread-3run1time(s) Thread-3run2time(s)
4.3使用FixedThreadPool启动线程
FixedThreadPool.java
packagecom.zj.concurrency.executors;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
publicclassFixedThreadPool{
publicstaticvoidmain(String[]args){
ExecutorServiceexec=Executors.newFixedThreadPool(2);
for(inti=0;i<5;i++)
exec.execute(newMyThread(i));
exec.shutdown();
}
}
结果:
CreateThread-0 CreateThread-1 CreateThread-2 CreateThread-3 CreateThread-4 Thread-0run1time(s) Thread-0run2time(s) Thread-2run1time(s) Thread-2run2time(s) Thread-3run1time(s) Thread-3run2time(s) Thread-4run1time(s) Thread-4run2time(s) Thread-1run1time(s) Thread-1run2time(s)
4.4使用SingleThreadExecutor启动线程
SingleThreadExecutor.java
packagecom.zj.concurrency.executors;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
publicclassSingleThreadExecutor{
publicstaticvoidmain(String[]args){
ExecutorServiceexec=Executors.newSingleThreadExecutor();
for(inti=0;i<5;i++)
exec.execute(newMyThread(i));
exec.shutdown();
}
}
结果:
CreateThread-0 CreateThread-1 CreateThread-2 CreateThread-3 CreateThread-4 Thread-0run1time(s) Thread-0run2time(s) Thread-1run1time(s) Thread-1run2time(s) Thread-2run1time(s) Thread-2run2time(s) Thread-3run1time(s) Thread-3run2time(s) Thread-4run1time(s) Thread-4run2time(s)
5.配合ThreadFactory接口的使用
我们试图给线程加入daemon和priority的属性设置。
5.1设置后台线程属性
DaemonThreadFactory.java
packagecom.zj.concurrency.executors.factory;
importjava.util.concurrent.ThreadFactory;
publicclassDaemonThreadFactoryimplementsThreadFactory{
publicThreadnewThread(Runnabler){
Threadt=newThread(r);
t.setDaemon(true);
returnt;
}
}
5.2设置优先级属性
最高优先级MaxPriorityThreadFactory.java
packagecom.zj.concurrency.executors.factory;
importjava.util.concurrent.ThreadFactory;
publicclassMaxPriorityThreadFactoryimplementsThreadFactory{
publicThreadnewThread(Runnabler){
Threadt=newThread(r);
t.setPriority(Thread.MAX_PRIORITY);
returnt;
}
}
最低优先级MinPriorityThreadFactory.java
packagecom.zj.concurrency.executors.factory;
importjava.util.concurrent.ThreadFactory;
publicclassMinPriorityThreadFactoryimplementsThreadFactory{
publicThreadnewThread(Runnabler){
Threadt=newThread(r);
t.setPriority(Thread.MIN_PRIORITY);
returnt;
}
}
5.3启动带有属性设置的线程
ExecFromFactory.java
packagecom.zj.concurrency.executors;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importcom.zj.concurrency.executors.factory.DaemonThreadFactory;
importcom.zj.concurrency.executors.factory.MaxPriorityThreadFactory;
importcom.zj.concurrency.executors.factory.MinPriorityThreadFactory;
publicclassExecFromFactory{
publicstaticvoidmain(String[]args)throwsException{
ExecutorServicedefaultExec=Executors.newCachedThreadPool();
ExecutorServicedaemonExec=Executors
.newCachedThreadPool(newDaemonThreadFactory());
ExecutorServicemaxPriorityExec=Executors
.newCachedThreadPool(newMaxPriorityThreadFactory());
ExecutorServiceminPriorityExec=Executors
.newCachedThreadPool(newMinPriorityThreadFactory());
for(inti=0;i<10;i++)
daemonExec.execute(newMyThread(i));
for(inti=10;i<20;i++)
if(i==10)
maxPriorityExec.execute(newMyThread(i));
elseif(i==11)
minPriorityExec.execute(newMyThread(i));
else
defaultExec.execute(newMyThread(i));
}
}
结果:
CreateThread-0 CreateThread-1 CreateThread-2 CreateThread-3 Thread-0run1time(s) Thread-0run2time(s) Thread-1run1time(s) Thread-1run2time(s) Thread-2run1time(s) Thread-2run2time(s) CreateThread-4 Thread-4run1time(s) Thread-4run2time(s) CreateThread-5 Thread-5run1time(s) Thread-5run2time(s) CreateThread-6 CreateThread-7 Thread-7run1time(s) Thread-7run2time(s) CreateThread-8 Thread-8run1time(s) Thread-8run2time(s) CreateThread-9 CreateThread-10 Thread-10run1time(s) Thread-10run2time(s) CreateThread-11 Thread-9run1time(s) Thread-9run2time(s) Thread-6run1time(s) Thread-6run2time(s) Thread-3run1time(s) Thread-3run2time(s) CreateThread-12 CreateThread-13 CreateThread-14 Thread-12run1time(s) Thread-12run2time(s) Thread-13run1time(s) Thread-13run2time(s) CreateThread-15 Thread-15run1time(s) Thread-15run2time(s) CreateThread-16 Thread-16run1time(s) Thread-16run2time(s) CreateThread-17 CreateThread-18 CreateThread-19 Thread-14run1time(s) Thread-14run2time(s) Thread-17run1time(s) Thread-17run2time(s) Thread-18run1time(s) Thread-18run2time(s) Thread-19run1time(s) Thread-19run2time(s) Thread-11run1time(s) Thread-11run2time(s)