Java并发编程之——线程池帮助类Executors和Future及Callable相关
Future和FutureTask
接口Future<V>表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用get()方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由cancel方法来执行,还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算了。如果为了可取消性而使用Future但又不提供可用的结果,则可以声明Future<?>形式类型,并返回null作为底层任务的结果。
Future主要定义了5个方法:cancle(boolean myaInterruptIfRunning)
isCancelled()
isDone():如果任务已完成,则返回true,可能由于正常终止,异常或取消而完成,在所有这些情况中,此方法都返回true
V get()如有必要,等待计算完成,然后获取其结果
V get(long timeout,TimeUnit unit):如有必要,最多等待为使用计算完成所给定的时间之后,获取其结果(如果结果可用)
FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过
Executor(线程池) 来执行。也可传递给Thread对象执行。
如果在主线程中需要执行比较耗时的操作时,但又不想阻塞主线程时,可以把这些作业交给
Future对象在后台完成,当主线程将来需要时,就可以通过Future对象获得后台作业的计算结果或者执行状态。Callable要采用ExecutorService的submit方法提交,返回的future对象可以取消任务。
threadPool.submit(callable<>)调用callable可返回值的线程,返回结果给future,
future.get()返回结果
CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务对应的Future对象。
下面是一个示例:
1 import java.util.Random; 2 import java.util.concurrent.Callable; 3 import java.util.concurrent.CompletionService; 4 import java.util.concurrent.ExecutorCompletionService; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.Executors; 7 import java.util.concurrent.Future; 8 9 public class FutureAndCallableTest { 10 11 public static void main(String[] args)throws Exception { 12 testSingleFutureAndCallable(); 13 testMultFutureAndCallable(); 14 } 15 16 /** 17 *测试只有一个线程一个任务的Future 18 */ 19 public static void testSingleFutureAndCallable()throws Exception{ 20 ExecutorService service = Executors.newSingleThreadExecutor(); 21 22 Future<String> future = service.submit(new Callable<String>(){ 23 @Override 24 public String call() throws Exception { 25 Thread.sleep(3000); 26 return "Hello"; 27 } 28 }); 29 30 System.out.println("等待拿到结果:"); 31 System.out.println(future.get()); 32 service.shutdown(); 33 34 } 35 /** 36 * 提交一组callable,谁先完成就拿谁的结果 37 * @throws Exception 38 */ 39 public static void testMultFutureAndCallable()throws Exception{ 40 //新建了一个固定线程池 41 ExecutorService service = Executors.newFixedThreadPool(10); 42 //CompletionService 可以将已完成任务与未完成的任务分离出来 ExecutorCompletionService此类将安排那些完成时提交的任务,把它们放置在可使用 take 访问的队列上 43 CompletionService<String> completionService = new ExecutorCompletionService<String>(service); 44 //加入10个输出字符串的任务,并使每个任务随机停留时间在3秒内 45 for(int i=0;i<10;i++){ 46 final int num = i; 47 completionService.submit(new Callable<String>(){ 48 @Override 49 public String call() throws Exception { 50 Thread.sleep(new Random().nextInt(3000)); 51 return "hello"+num; 52 } 53 }); 54 } 55 //获取任务的结果 56 for(int j=0;j<10;j++){ 57 58 Future<String> future =completionService.take(); 59 System.out.println(future.get()); 60 } 61 //关闭线程池 62 service.shutdown(); 63 64 } 65 66 }