FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行。今天我们通过实例来学习一下FutureTask的用法。
多线程中FutureTask的使用
一、FutureTask的简单使用
package com.huhx.chenhui.nio; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class CallableThreadTest implements Callable<Integer> { public static void main(String[] args) { CallableThreadTest threadTest = new CallableThreadTest(); FutureTask<Integer> future = new FutureTask<>(threadTest); for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + " 的循环变更i的值" + i); if (i == 2) { new Thread(future, "有返回的线程").start(); } } try { System.out.println("子线程的返回值:" + future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } @Override public Integer call() throws Exception { int i = 0; for (; i < 10; i++) { System.out.println(Thread.currentThread().getName() + "" + i); } return i; } }
运行结果如下:
main 的循环变更i的值0 main 的循环变更i的值1 main 的循环变更i的值2 main 的循环变更i的值3 main 的循环变更i的值4 main 的循环变更i的值5 main 的循环变更i的值6 main 的循环变更i的值7 main 的循环变更i的值8 main 的循环变更i的值9 有返回的线程0 有返回的线程1 有返回的线程2 有返回的线程3 有返回的线程4 有返回的线程5 有返回的线程6 有返回的线程7 有返回的线程8 有返回的线程9 子线程的返回值:10
二、 FutureTask的get方法的超时测试
package com.linux.huhx.thread; import java.util.concurrent.*; public class FutureTest { public static void main(String[] args) throws TimeoutException { FutureTask<String> future = new FutureTask<String>(new Task()); new Thread(future).start(); try { System.out.println(future.get(4L, TimeUnit.SECONDS)); System.out.println("main thread"); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } static class Task implements Callable<String> { @Override public String call() throws Exception { System.out.println("begin: " + Thread.currentThread().getName() + ", " + System.currentTimeMillis()); TimeUnit.SECONDS.sleep(5); return "hello"; } } }
运行的效果如下:
官方文档对于这个方法的说明如下:
Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.
FutureTask的原理分析
FutureTask类的继承结构如下:
public class FutureTask<V> implements RunnableFuture<V> public interface RunnableFuture<V> extends Runnable, Future<V>
FutureTask重写了run()方法,代码如下:
public void run() { if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); // 调用Callable类中的call方法 ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }
FutureTask的get方法,得到线程执行返回的结果。
Object x = outcome; if (s == NORMAL) return (V)x;
友情链接