直接上代码
package com.itbac.thread; import java.util.Iterator; import java.util.concurrent.Callable; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.LockSupport; /** * 手写FutureTask获取异步线程执行结果 */ public class BacFutureTask<T> implements Runnable{ Callable<T> callable; //任务结果 T result; //任务状态: 0 初始状态,1 任务执行完成 volatile int state = 0; //等待队列 LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>(); public BacFutureTask() { } public BacFutureTask(Callable<T> callable) { this.callable = callable; } @Override public void run() { try { result = callable.call(); } catch (Exception e) { e.printStackTrace(); }finally { state = 1; //线程唤醒 if (!waiters.isEmpty()) { Iterator<Thread> iterator = waiters.iterator(); while (iterator.hasNext()) { Thread next = iterator.next(); LockSupport.unpark(next); } } } } //获取异步任务的结果 public T get() { while (0 == state) { //加入等待集合 waiters.add(Thread.currentThread()); if (0 == state) { //再次判断,为了安全。 // 确保当前线程一定进入等待集合后, // 异步线程state = 1还没执行,才能挂起 LockSupport.park(); } //从集合中删除 waiters.remove(Thread.currentThread()); } return result; } }
测试:
package com; import com.itbac.thread.BacFutureTask; import java.util.concurrent.Callable; public class BacFutureTaskTest { public static void main(String[] args) { BacFutureTask<String> futureTask = new BacFutureTask<>(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(1000); System.out.println("异步任务开始执行。"); //TODO 复杂的业务逻辑 return "异步任务结果"; } }); new Thread(futureTask).start(); String s = futureTask.get(); System.out.println(s); } }
输出:
异步任务开始执行。
异步任务结果