java多线程学习-java.util.concurrent详解(四) Exchanger
转载于:http://janeky.iteye.com/blog/769965
我们先来学习一下JDK1.5 API中关于这个类的详细介绍:
“取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对 Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。
可使用 FutureTask 包装 Callable 或 Runnable 对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor 执行。
除了作为一个独立的类外,此类还提供了 protected 功能,这在创建自定义任务类时可能很有用。 “
应用举例:我们的算法中有一个很耗时的操作,在编程的是,我们希望将它独立成一个模块,调用的时候当做它是立刻返回的,并且可以随时取消的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | package com.winterbe.java8.samples.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; public class TestFutureTask { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); FutureTask<String> task = new FutureTask<String>( new Callable<String>() { // FutrueTask的构造参数是一个Callable接口 @Override public String call() throws Exception { Thread.sleep( 8 * 1000 ); return Thread.currentThread().getName() + ":0" ; // 这里可以是一个异步操作 } }); FutureTask<String> task1 = new FutureTask<String>( new Callable<String>() { // FutrueTask的构造参数是一个Callable接口 @Override public String call() throws Exception { Thread.sleep( 4 * 1000 ); return Thread.currentThread().getName() + ":1" ; // 这里可以是一个异步操作 } }); try { exec.execute(task); // FutureTask实际上也是一个线程 Thread.sleep( 1 * 1000 ); // 睡眠2S,相当于等待方法执行2S,如果还没有执行完成,则取消该线程的执行 if (!task.isDone()) { System.out.println( "Time out,cancel the " + Thread.currentThread().getName() + ":0" + "." ); task.cancel( true ); // 取消 } if (!task.isCancelled()) { String result = task.get(); // 取得异步计算的结果,如果没有返回,就会一直阻塞等待 System.out.printf( "get:%s%n" , result); } exec.execute(task1); Thread.sleep( 4 * 1000 ); if (!task1.isDone()) { System.out.println( "Time out,cancel the " + Thread.currentThread().getName() + ":1" + "." ); task1.cancel( true ); // 取消 } if (!task1.isCancelled()) { String result1 = task1.get(); System.out.printf( "get:%s%n" , result1); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } |
总结:FutureTask其实就是新建了一个线程单独执行,使得线程有一个返回值,方便程序的编写
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步