Java并发----Callable、Future和FutureTask

来源:互联网 发布:js执行点击事件 编辑:程序博客网 时间:2024/05/09 07:49

Callable、Future和FutureTask

创建线程一般使用Thread或者实现Runnable接口,这种缺陷是执行完毕之后是无法获取到结果的。(run()返回是void)。
如果想获取到结果需要使用共享变量或者线程之间的通信获取,如此做不仅繁琐对编程能力有要求比较高。
从JAVA1.5提供了Callable、Future来使线程执行完毕之后返回结果。



下面是我总结的使用Callable、Future和FutureTask的使用方法:

1.Callable位于java.util.concurrent包,里面只声明了一个方法call();(类似run(),但是它是有返回结果类型的--V);
public interface Callable<V> {    /**     * Computes a result, or throws an exception if unable to do so.     *     * @return computed result     * @throws Exception if unable to compute a result     */    V call() throws Exception;}
一般配合ExecutorService类来使用,这个类中有submit方法:
<T> Future<T> submit(Callable<T> task);<T> Future<T> submit(Runnable task, T result);Future<?> submit(Runnable task);
一般情况下我们只使用第一个和第三个,第二个很少使用。
它们返回的都是Future,我们来看看这个是怎么使用的。

2.Future
Future就是对Callable和Runnable任务的执行结果进行取消、查询是否完成、获取结果等操作。必要时可通过get()获取结果,任务阻塞直到任务返回结果。

Future类位于java.util.concurrent包下:
public interface Future<V> {    boolean cancel(boolean mayInterruptIfRunning);    boolean isCancelled();    boolean isDone();    V get() throws InterruptedException, ExecutionException;    V get(long timeout, TimeUnit unit)        throws InterruptedException, ExecutionException, TimeoutException;}
cancel方法用来取消任务,如果任务取消则返回成功true,否则返回fasle。-----mayInterruptIfRunning表示是否允许取消正在执行但没有执行完毕的任务,如果设置true,则表示允许取消。

isCancelled方法表示任务是否被取消成功。

isDone方法表示任务是否已经完成。

get方法表示用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回。

get(long timeout,TimeUnit unit)用来获取执行结果,如果在指定时间内未获取到则直接返回null。

此接口定义了许多对线程执行结果的一些验证和返回。具体实现类FutureTask才是核心。

3.FutureTask
FutureTask是Future接口的唯一实现类。
它实现了RunnableFuture接口,而这接口又继承了Runnable和Future接口。所以它可作为Runnable被线程执行,又可以作为Callable的返回值。


-------------------------------------------  使用案例  -------------------------------------------------

使用Callable和Future获取执行结果:
List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();<span style="white-space:pre"></span>Map<String, Object> params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果1");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果2");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果3");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果4");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果5");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果6");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果7");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果8");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果9");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果10");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果11");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果12");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果13");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果14");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果15");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果16");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果17");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果18");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果19");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>params = new HashMap<String, Object>();<span style="white-space:pre"></span>params.put("taskName", "结果20");<span style="white-space:pre"></span>list.add(params);<span style="white-space:pre"></span>Task<String> task = new SendTask();<span style="white-space:pre"></span>long start = System.currentTimeMillis();<span style="white-space:pre"></span>List<Future<String>> results = TaskHandler.dealTask(list, task,10000);<span style="white-space:pre"></span>long end = System.currentTimeMillis();<span style="white-space:pre"></span>System.out.println(end-start);<span style="white-space:pre"></span>int i=0;<span style="white-space:pre"></span>for (Future<String> f : results) {<span style="white-space:pre"></span>i++;<span style="white-space:pre"></span>System.out.println("返回结果:"+i);<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>System.out.println(f.get());<span style="white-space:pre"></span>} catch (Exception e) {<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}


public class SendTask implements Task<String>{<span style="white-space:pre"></span><span style="white-space:pre"></span>private Map<String, Object> params;<span style="white-space:pre"></span><span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void taskParams(Map<String, Object> params) {<span style="white-space:pre"></span>this.params = params;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public String call() throws Exception {<span style="white-space:pre"></span>System.out.println("线程等待2s");<span style="white-space:pre"></span>Thread.sleep(2000);<span style="white-space:pre"></span>System.out.println(params.get("taskName"));<span style="white-space:pre"></span>return "返回成功!";<span style="white-space:pre"></span>}}

public static  <T>List<Future<T>> dealTask(List<Map<String, Object>> params,Task<T> task,long timeOut){List<Future<T>> list = new ArrayList<Future<T>>();//获取缓存线程池ExecutorService service = ThreadLocalHelper.getCachedPool();// 执行多任务,循环处理参数集Future<T> future = null;//初始化返回结果集for (Map<String, Object> param : params) {try {// 给任务设置任务参数task.taskParams(param);//执行任务future = service.submit(task);list.add(future);} catch (Exception e) {e.printStackTrace();} }//执行完毕后关闭线程池service.shutdown();//获取开始时间(若超过20S,则强制退出返回)long start = System.currentTimeMillis();long flag = 0;while(true){flag = System.currentTimeMillis()-start;if(service.isTerminated()||flag>=timeOut){System.out.println("线程执行完毕!");break;}try {Thread.sleep(10);} catch (Exception e) {e.printStackTrace();}}return list;}























0 0