假设有如下逻辑,实现快递员取餐后送餐:
外卖平台发布客户订餐消息,商家开始备货,同时快递员抢单
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方法一样,都会同样阻塞主线程,如以上例子中,主线程外卖平台在当前单子处理完成之前,不能够再接收和发布其他订单消息了