右耳菌-邓小白的Java架构师的修炼之路

Java并发 - FetureTask的例子

2022-06-22  本文已影响0人  右耳菌

先看一下相关的例子

package futureTask;

import java.util.concurrent.*;

public class ThreadTest_Demo {

    static ExecutorService executors = Executors.newScheduledThreadPool(2);

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                String str = "返回某个数据!";
                return str;
            }
        };

        Future<String> submit = executors.submit(callable); // 因为使用的是线程池,所以会执行完之后并不会结束运行
        System.out.println(submit.get()); // 会阻塞等待结果返回

        FutureTask<String> futureTask = new FutureTask<>(callable);
        new Thread(futureTask).start();
        System.out.println(futureTask.get()); // 会阻塞等待结果返回

    }
}

本质就是一个异步获取结果的多线程,可以使用在同时请求多个数据源的内容,然后一起返回的情况下。

package futureTask;

import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.LockSupport;

public class MyFutureTask<T> implements Runnable {

    private Callable<T> callable;

    T result;

    volatile String state = "NEW";

    LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();

    public MyFutureTask(Callable<T> callable) {
        this.callable = callable;
    }

    public T get() { //阻塞,等待run方法执行完毕.
        if ("END".equals(state)) {
            return result;
        }

        while (!"END".equals(state)) { //开始执行阻塞.
            //准备一个容器,通过这个容器来去存放线程。
            waiters.offer(Thread.currentThread());
            LockSupport.park(); // 阻塞等待run执行结束
        }
        return result;
    }

    @Override
    public void run() {
        try {
            result = callable.call();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            state = "END";
        }
        Thread waiter = waiters.poll();
        while (waiter != null) {
            LockSupport.unpark(waiter);
            waiter = waiters.poll(); // 如果有多个线程获取
        }
    }
}

执行代码

package futureTask;

import java.util.concurrent.Callable;

public class ThreadTest_Demo {

    public static void main(String[] args) {

        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() {
                String str = "返回某个数据!";
                return str;
            }
        };

        MyFutureTask<String> futureTask = new MyFutureTask<>(callable);
        new Thread(futureTask).start();
        System.out.println(futureTask.get()); // 会阻塞等待结果返回
    }
}

执行结果

返回某个数据!

如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

上一篇下一篇

猜你喜欢

热点阅读