前面已经指出通过实现Runnable时,Thread类的浸染就是将run()要领包装成线程执行体,那么是否可以直接把任意要领都包装成线程执行体呢?Java今朝不可,但其仿照者C#中是可以的.
Callabel接口可以当作是Runnable接口的加强版,只不外其线程执行体call()要领比run要领越发强大而已:
>>call()要领中可以有返回值
>>call()要领中可以声明抛出异常.
一.建设线程的第三种方法—-利用Callable工具举办建设
package com.amos.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * @ClassName: CallableAndFuture * @Description: 多线程中的Callable和Future进修 * @author: amosli * @email:hi_amos@outlook.com * @date Apr 22, 2014 12:07:26 AM */ public class CallableAndFuture { public static void main(String[] args) throws Exception, ExecutionException { ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor(); Future<String> future = newSingleThreadExecutor.submit(new Callable<String>() { public String call() throws Exception { Thread.sleep(20); return "hi,amos"; } }); // System.out.println("future:"+future.get(1,TimeUnit.MILLISECONDS));//期待指定的时间 System.out.println("future:" + future.get()); } }
结果如下:
注:
本栏目
1.这里要留意的是,建设线程时执行任务不是用execute()要领去执行了,而是用submit()要领.
2.同时要留意,这里call()要领返回值,要和上面的保持一致.
3.别的,可以配置最大期待时间,就是期待措施的返回值,这里利用get()要领.
4.其常用的其它要领有cancel(),isCancelled(),isDone(),别离暗示打消关联的任务,是否已经打消,任务是否已经完成.
二.CompeltionService
CompeltionService主要用于提交一组Callable工具,其take要领用于返回已完成的callable任务的Future工具.可以用麦子收割来作比喻,种了10亩地的麦子,哪一块先成熟先收割哪一块.
举例:
package com.amos.concurrent; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CallableAndFuture { public static void main(String[] args) throws Exception, ExecutionException { ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(newFixedThreadPool); for(int i=0;i<11;i++){//建设10个任务 final int task=i; completionService.submit(new Callable<Integer>() {//提交任务 public Integer call() throws Exception { Thread.sleep(new Random().nextInt(3000));//最多3秒 return task; } }); } //take for(int i=0;i<11;i++){ System.out.println("已完成的任务:"+completionService.take().get()); } }
结果如下图所示:
注:由功效也可以看出来,其随机功效是按照任务的先后完成顺序来的,利用其take()要领可以获取其返回功效.