FutureTask:一种可以携带结果的Runnable.它的计算是通过Callable的call方法来实现的。
我们来看一下FutureTask的构造.
public class FutureTask<V> implements RunnableFuture<V>
可以看到它实现了RunnableFuture接口.
public interface RunnableFuture<V> extends Runnable, Future<V>
而RunnableFuture又实现了Runnable和Future。
Runnable接口想必大家都非常熟悉了。我们来看下Future接口
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(boolean mayInterruptIfRunning) | 取消任务,如果mayInterruptIfRunning设置为true,标识可以取消正在进行中的任务.返回值分为三种情况:1.任务执行中,当mayInterruptIfRunning为true时,返回true.当mayInterruptIfRunning为false时候返回false.2.任务已经完成.无论mayInterruptIfRunning为true or false 都返回false.3.任务未运行 .无论mayInterruptIfRunning为true or false 都返回true |
isCancelled() | 任务是否被成功取消 |
isDone() | 任务是否已经完成.取消、异常、完成都属于完成。 |
get() | 阻塞只到有结果返回 |
get(long timeout, TimeUnit unit) | 指定时间内如果没有返回结果则返回NULL |
我们再来看下FutureTask的构造器
public FutureTask(Callable<V> callable) 中有一个Callable参数。上面我们说过FutureTask的计算实际是通过Callable的call方法来实现的。
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; }
Callable接口中只有一个call方法,而且有返回值,这个返回值就是我们计算所携带的结果。
下面是FutureTask的常见用法:
1.Thread 执行FutureTask
package com.asiainfo.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; /** * 可携带结果的任务. * * 实现了Runnable接口 */ import java.util.concurrent.FutureTask; /** * Thread 方式启动FutureTask * @author fansh * */ public class FutureTaskTest{ static FutureTask<String> future=new FutureTask<String>(new Callable<String>() { public String call() throws Exception { return "this is the result!"; }; }); private Thread thread = new Thread(future); private void start(){ thread.start(); } public static void main(String[] args) { FutureTaskTest test =new FutureTaskTest(); test.start(); try { String result=future.get(); System.out.println(result); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
2. ExecutorService启动FutureTask
package com.asiainfo.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.FutureTask; /** * ExecutorService 方式启动FutureTask * @author fansh * */ public class FutureTaskTest1 { static FutureTask<String> future = new FutureTask<String>(new Callable<String>(){ public String call(){ return "this is the result!"; } }); public static void main(String[] args) throws InterruptedException, ExecutionException{ ExecutorService service =Executors.newCachedThreadPool(); service.submit(future); service.shutdown(); String result=future.get(); System.out.println(result); } }
3.FutureTask 任务未启动时 取消任务
package com.asiainfo.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * 1:任务尚未开始 * @author fansh * */ public class FutureTaskCanceledTest { static FutureTask<String> future=new FutureTask<String>(new Callable<String>() { public String call() throws Exception { Thread.sleep(1000); return "a"; }; }); private Thread thread = new Thread(future); private void start(){ thread.start(); } public static void main(String[] args) { FutureTaskCanceledTest test =new FutureTaskCanceledTest(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //boolean flag =future.cancel(true); boolean flag =future.cancel(false); System.out.println("任务是否已经取消:"+flag); //保证任务取消的时候 线程尚未执行. test.start(); } }
4.FutureTask 任务完成后 取消任务
package com.asiainfo.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * 1:任务已经完成 * @author fansh * */ public class FutureTaskCanceledTest1 { static FutureTask<String> future=new FutureTask<String>(new Callable<String>() { public String call() { return "a"; }; }); private Thread thread = new Thread(future); private void start(){ thread.start(); } public static void main(String[] args) { FutureTaskCanceledTest1 test =new FutureTaskCanceledTest1(); test.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } boolean flag=future.cancel(false); //boolean flag=future.cancel(true); System.out.println("任务是否已经取消:"+flag); } }
5. 任务进行中 响应取消动作
package com.asiainfo.concurrent; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; /** * 1:任务进行中...... * @author fansh * */ public class FutureTaskCanceledTest2 { static FutureTask<String> future=new FutureTask<String>(new Callable<String>() { public String call() { while(!Thread.currentThread().isInterrupted()){ System.out.println("任务进行中............"); } return "a"; }; }); private Thread thread = new Thread(future); private void start(){ thread.start(); } public static void main(String[] args) { FutureTaskCanceledTest2 test =new FutureTaskCanceledTest2(); test.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } boolean flag=future.cancel(true); //boolean flag=future.cancel(false); System.out.println("任务是否已经取消:"+flag); } }