Join和FutureTask

假设有如下逻辑,实现快递员取餐后送餐:

外卖平台发布客户订餐消息,商家开始备货,同时快递员抢单

1、商家:起锅烧油,炒菜,盛饭,打包

2、快递员:抢单,规划路线,赶路,到店

Join实现

        Thread merchant = new Thread() {
            @Override
            public void run() {
                try {
                    logger.info("起锅烧油");
                    logger.info("炒菜");
                    // 5s炒菜时间
                    Thread.sleep(5000);
                    logger.info("盛饭");
                    logger.info("打包");

                } catch (Exception e) {
                    logger.error("", e);
                }
            }
        };

        merchant.setName("merchant");

        Thread courier = new Thread() {
            @Override
            public void run() {
                try {
                    logger.info("抢单");
                    logger.info("规划路线");
                    // 3s赶路时间
                    Thread.sleep(3000);
                    logger.info("赶路");
                    logger.info("到店");

                } catch (Exception e) {
                    logger.error("", e);
                }
            }
        };
        courier.setName("courier");

        merchant.start();
        courier.start();

        try {
            courier.join();
            merchant.join();
        } catch (InterruptedException e) {
            logger.info("", e);
        }
        
        logger.info("快递员开始送餐 。。。");
    

FutureTask实现

        Callable<Boolean> merchantCall = new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                try {
                    logger.info("起锅烧油");
                    logger.info("炒菜");
                    // 5s炒菜时间
//                    int i =1/0; // 模擬商家
                    Thread.sleep(5000);
                    logger.info("盛饭");
                    logger.info("打包");
                } catch (Exception e) {
                    logger.error("", e);
                    return false;
                }
                return true;
            }

        };

        Callable<Boolean> courierCall = new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                try {
                    logger.info("抢单");
                    logger.info("规划路线");
                    // 3s赶路时间
//                    int i=1/0; // 车子被偷
                    Thread.sleep(3000);
                    logger.info("赶路");
                    logger.info("到店");
                } catch (Exception e) {
                    logger.error("", e);
                    return false;
                }
                return true;
            }
        };

        FutureTask<Boolean> merchantFT = new FutureTask<Boolean>(merchantCall);
        FutureTask<Boolean> courierFT = new FutureTask<Boolean>(courierCall);

        Thread merchant = new Thread(merchantFT);
        Thread courier = new Thread(courierFT);

        merchant.setName("merchant");
        courier.setName("courier");

        merchant.start();
        courier.start();

        boolean merchantResult = false;
        boolean courierResult = false;
        try {
            merchantResult = merchantFT.get();
            courierResult = courierFT.get();
        } catch (InterruptedException | ExecutionException e) {
            logger.error("", e);
        }

        if (merchantResult && courierResult) {
            logger.info("快递员开始送餐 。。。");
        } else if (merchantResult && !courierResult) {
            logger.error("外卖员车子被偷了,不能够送餐");
        } else if (!merchantResult && courierResult) {
            logger.error("商家厨师家里临时有事,请假了,做不了饭");
        } else {
            logger.error("外卖员车子被偷,商家厨师请假了 。。。 ");
        }

    

Join:
A线程调用B线程的join方法,等待B线程执行完成后,A线程才可以执行后续操作。在B线程完成之前,A线程处于阻塞状态。
1、join方法需要线程对象调用
2、调用join时,当前线程被阻塞
3、只有join对应的线程执行完成之后,当前线程才能继续执行

4、join方法无法获得线程执行结果

FutureTask:
1、个人认为futuretask比join最大的好处就是可以获取返回值,可以知道每条线程运行的具体的情况。以上例子join方法实现,即便是商家或者快递员一方出现问题,也会最终出现“快递员开始送餐”。

2、但futuretask和join方法一样,都会同样阻塞主线程,如以上例子中,主线程外卖平台在当前单子处理完成之前,不能够再接收和发布其他订单消息了

原文地址:https://www.cnblogs.com/qq931399960/p/15555152.html