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)