Runnable runnable = new Runnable(){ public void run(){ System.out.println("Run"); } }
你能够简单的在壹個线程中运行它: html
new Thread(runnable).start();
这個代码很简洁,可是若是咱们想并行的启动多個任务该怎么办呢,并且咱们还想等待全部任务完成以后获取全部任务的返回值,这样的话,要想保持较好的代码风格实际上有点困难了。不过,就像全部其它的难题壹样,Java 为咱们提供了壹個解决方案,那就是 Executor ,这個简单的类容许你建立线程池和线程工厂。 java
ExecutorService executor = Executors.newFixedThreadPool(5); for (int i = 0; i < 10; i++) { executor.execute(new Runnable() { public void run() { System.out.println("do something here..."); } }); } executor.shutdown();线程池实际表现为 ExecutorService 类的壹個实例。经过使用 ExecutorService ,你能够提交将在将来完成的任务。经过 Executor 类你能够建立以下几种线程池:
一、Single Thread Executor:只有壹個线程的线程池。因此全部提交的任务都会被顺序执行。方法名称:Executors.newSingleThreadExecutor();
二、Cache Thread Pool:壹個建立足够多的线程的线程池,能够并行的执行全部任务。旧的线程会被从新用于新的任务。若是线程在60秒内没有被用到,这個线程就会被终止而且从线程池中移除掉。方法名称:Executors.newCachedThreadPool();
三、Fixed Thread Pool:壹個有着固定数量的线程的线程池。若是对于某個任务而言某线程不可用,这個任务会被放进队列中等待其它的任务完成以后再执行。方法名称:Executors.newFixedThreadPool();
四、Scheduled Thread Pool:壹個为定时任务准备的线程池。方法名称:Executors.newScheduledThreadPool();
五、Single Thread Scheduled Pool:壹個为定时的将来的任务准备的单個线程的线程池,方法名称:Executors.newSingleThreadScheduledExecutor();
壹旦你有了壹個线程池,你可使用上述不一样的提交方法提交你的任务了。你能够提交壹個 Runnable 或者 Callable 的任务到线程池中。这個方法返回壹個 Future 对象,用于表示这個任务在将来的状态。若是你提交壹個 Runnable 的任务,那么壹旦任务结束, Future 将返回 null 。
举個例子,若是你有以下这样壹個 Callable 的任务: 算法
private final class StringTask implements Callable<String> { public String call(){ //耗时的操做 return "Run"; } }
若是你但愿使用4個线程执行该任务10次,你可使用以下代码: api
ExecutorService pool = Executors.newFixedThreadPool(4); for(int i = 0; i < 10; i++){ pool.submit(new StringTask()); }可是你必须关闭线程池才能结束池中的全部线程:
pool.shutdown();若是你不这样作,Java 虚拟机就存在不能关闭的风险,由于仍然有线程没有终止。如今你可使用 shutdown() 方法强制关闭线程池,可是这样壹来当前正在执行的任务将会被中断,而没有启动的线程永远都不会再启动了。
ExecutorService pool = Executors.newFixedThreadPool(4); List<Future<String>> futures = new ArrayList<Future<String>>(10); for(int i = 0; i < 10; i++){ futures.add(pool.submit(new StringTask())); } for(Future<String> future : futures){ String result = future.get(); //计算结果 } pool.shutdown();可是使用这种代码略有点复杂,并且有個缺点。若是第壹個任务花了很长时间去计算,而其它任务在它以前先结束了,当前线程在第壹個线程结果以前就不能计算结果。再壹次,Java 为咱们提供了壹個解决方案,这就是 CompletionService 。
ExecutorService threadPool = Executors.newFixedThreadPool(4); CompletionService<String> pool = new ExecutorCompletionService<String>(threadPool); for(int i = 0; i < 10; i++){ pool.submit(new StringTask()); } for(int i = 0; i < 10; i++){ String result = pool.take().get(); //计算结果 } threadPool.shutdown();经过这种方式,你能够按照它们完成任务的顺序得到结果而没必要持有壹個全部 Future 对象的集合。
本文英文原文出自 http://www.baptiste-wicht.com/2010/09/java-concurrency-part-7-executors-and-thread-pools/,中文翻译首发开源中国社区 http://my.oschina.net/bairrfhoinn/blog/167113,转载请注明原始出处。 并发
2013-10-21 09:54:00 更新:刚刚发现这篇文章的翻译文章,红薯已经在以前的讨论版块发过了,连接见于 http://www.oschina.net/question/12_11255 ,貌似我重复造轮子了,汗壹個! oracle