FutureTask为什么就做到比Join更精细的控制

来源:8-4 如何实现处理线程的返回值

YogurtJ

2020-01-29

老师课上讲的: Join方法能做到比主线程等待法更精准的控制,它的缺点是粒度不够细,以RunnableDemo为例子,比如说我Runnable1里面的 i = 5的时候去执行Runnable2 里面的run方法,
这种更精准的依赖关系join方法是无法做到的
可我也没有想通FutureTask 通过isDone 和 get方法就如何可以做到
"比如说我Runnable1里面的 i = 5的时候去执行Runnable2 里面的run方法" 呢?

希望老师可以用代码的例子解答一下

写回答

1回答

翔仔

2020-01-30

同学好,当时说的这句话应该是有问题的,当时主要是想表达FutureTask能够更精细地控制线程执行流程才这样说的,如果仅通过线程1去控制线程2的话,靠isDone和get确实没法控制线程1在执行到一半的时候去执行线程2的流程,因为isDone是瞬时操作,返回的值不确定,而get则只能返回终态。所以只能按照如下方式进行,但是没有用到isDone和get,

public class FutureTaskDemo {
    public static void main(String[] args) {
        class Task1 implements Callable<String> {
            @Override
            public String call() throws Exception {
                System.out.println("产品经理规划新需求");
                return null;
            }
        }

        class Task2 implements Callable<String> {
            private FutureTask<String> task1;
            private ExecutorService executorService;

            public Task2(FutureTask<String> task, ExecutorService executorService) {
                this.task1 = task;
                this.executorService = executorService;
            }

            @Override
            public String call() throws Exception {
                Thread.sleep(2000);
                for(int i = 0; i< 10; i++){
                    if(i == 5){
                        this.executorService.submit(task1);
                    }
                }
                System.out.println("开发人员开发新需求功能");
                return null;
            }
        }
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        FutureTask<String> futureTask1 = new FutureTask<>(new Task1());
        FutureTask<String> futureTask2 = new FutureTask<>(new Task2(futureTask1, executorService));
        executorService.submit(futureTask2);
    }
}

如果想用futureTask的get来实现这样的控制,得多一个task3,通过让确保task3执行完成也就是打印到5之后,才执行task1

public class FutureTaskDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        class Task1 implements Callable<String> {
            @Override
            public String call() throws Exception {
                System.out.println("测试人员测试新需求功能");
                return null;
            }
        }

        class Task2 implements Callable<String> {
            @Override
            public String call() throws Exception {
                for(int i = 0; i< 10; i++){

                }
                System.out.println("开发人员开发新需求功能");
                return null;
            }
        }
        class Task3 implements Callable<String> {
            @Override
            public String call() throws Exception {
                for(int i = 0; i< 5; i++){

                }
                System.out.println("产品经理规划新需求");
                return "ok";
            }
        }
        ExecutorService executorService = Executors.newFixedThreadPool(6);
        FutureTask<String> futureTask1 = new FutureTask<>(new Task1());
        FutureTask<String> futureTask2 = new FutureTask<>(new Task2());
        FutureTask<String> futureTask3 = new FutureTask<>(new Task3());
        executorService.submit(futureTask3);
        executorService.submit(futureTask2);
        futureTask3.get();
        executorService.submit(futureTask1);
    }
}

如果要实现上述的精确控制,可以考虑

JAVA栅栏:CyclicBarrier

定义:多个线程相互等待执行到某个栅栏点的时候(就是执行了await),所有线程继续执行下去。

https://blog.csdn.net/jinjin603/article/details/81986171


1
1
YogurtJ
非常感谢!
2020-01-31
共1条回复

剑指Java面试-Offer直通车 百度资深面试官授课

招聘季即将到来,让百度资深面试官来为你的高薪Offer保驾护航

8451 学习 · 1872 问题

查看课程