手写FutureTask获取异步线程执行结果

直接上代码

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);


    }
}

输出:

异步任务开始执行。
异步任务结果

posted @ 2019-11-24 20:01  北溪  阅读(676)  评论(0编辑  收藏  举报