Java并发 - FetureTask的例子

作者: 右耳菌 | 来源:发表于2022-06-22 15:31 被阅读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()); // 会阻塞等待结果返回
    
        }
    }
    

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

    • 实现一个FutureTask
    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()); // 会阻塞等待结果返回
        }
    }
    

    执行结果

    返回某个数据!
    

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

    相关文章

      网友评论

        本文标题:Java并发 - FetureTask的例子

        本文链接:https://www.haomeiwen.com/subject/qykuvrtx.html