使用Executor
java.util.concurrent
CachedThreadPool
package concurrency.ExecutorService; //: concurrency/CachedThreadPool.java import java.util.concurrent.*; import concurrency.LiftOff.LiftOff; public class CachedThreadPool { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) exec.execute(new LiftOff()); exec.shutdown(); } } /* * Output: (Sample) #0(9), #0(8), #1(9), #2(9), #3(9), #4(9), #0(7), #1(8), * #2(8), #3(8), #4(8), #0(6), #1(7), #2(7), #3(7), #4(7), #0(5), #1(6), #2(6), * #3(6), #4(6), #0(4), #1(5), #2(5), #3(5), #4(5), #0(3), #1(4), #2(4), #3(4), * #4(4), #0(2), #1(3), #2(3), #3(3), #4(3), #0(1), #1(2), #2(2), #3(2), #4(2), * #0(Liftoff!), #1(1), #2(1), #3(1), #4(1), #1(Liftoff!), #2(Liftoff!), * #3(Liftoff!), #4(Liftoff!), */// :~
/** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available. These pools will typically improve the performance * of programs that execute many short-lived asynchronous tasks. * Calls to {@code execute} will reuse previously constructed * threads if available. If no existing thread is available, a new * thread will be created and added to the pool. Threads that have * not been used for sixty seconds are terminated and removed from * the cache. Thus, a pool that remains idle for long enough will * not consume any resources. Note that pools with similar * properties but different details (for example, timeout parameters) * may be created using {@link ThreadPoolExecutor} constructors. * * @return the newly created thread pool */ public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
以上,JDK里头关于Executors.newCachedThreadPool的定义。
通过创建线程池,去管理线程。并且,线程池通过exec.execute去启动新的线程。
newCachedThreadPool会为每一个任务创建一个线程。
FixedThreadPool
package concurrency.ExecutorService; //: concurrency/FixedThreadPool.java import java.util.concurrent.*; import concurrency.LiftOff.LiftOff; public class FixedThreadPool { public static void main(String[] args) { // Constructor argument is number of threads: ExecutorService exec = Executors.newFixedThreadPool(5); for (int i = 0; i < 5; i++) exec.execute(new LiftOff()); exec.shutdown(); } } /* * Output: (Sample) #0(9), #0(8), #1(9), #2(9), #3(9), #4(9), #0(7), #1(8), * #2(8), #3(8), #4(8), #0(6), #1(7), #2(7), #3(7), #4(7), #0(5), #1(6), #2(6), * #3(6), #4(6), #0(4), #1(5), #2(5), #3(5), #4(5), #0(3), #1(4), #2(4), #3(4), * #4(4), #0(2), #1(3), #2(3), #3(3), #4(3), #0(1), #1(2), #2(2), #3(2), #4(2), * #0(Liftoff!), #1(1), #2(1), #3(1), #4(1), #1(Liftoff!), #2(Liftoff!), * #3(Liftoff!), #4(Liftoff!), */// :~
newFixedThreadPool会创建指定个数的线程。
SingleThreadExecutor
package concurrency.ExecutorService; //: concurrency/SingleThreadExecutor.java import java.util.concurrent.*; import concurrency.LiftOff.LiftOff; public class SingleThreadExecutor { public static void main(String[] args) { ExecutorService exec = Executors.newSingleThreadExecutor(); for (int i = 0; i < 5; i++) exec.execute(new LiftOff()); exec.shutdown(); } } /* * Output: #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), * #0(Liftoff!), #1(9), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), * #1(Liftoff!), #2(9), #2(8), #2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), * #2(Liftoff!), #3(9), #3(8), #3(7), #3(6), #3(5), #3(4), #3(3), #3(2), #3(1), * #3(Liftoff!), #4(9), #4(8), #4(7), #4(6), #4(5), #4(4), #4(3), #4(2), #4(1), * #4(Liftoff!), */// :~
newSingleThreadExecutor线程数为一的newFixedThreadPool。
参考
Java编程思想(第4版) 656页开始
Thinking in Java(第四版 ) 1120页开始