当前位置: 首页 > 后端技术 > Java

面试题中Runnable和Callable的区别

时间:2023-04-01 21:21:43 Java

RunnableRunnable接口很简单,它定义了一个方法run(),实现Runnable接口的run方法可以实现多线程//Functionalinterface@FunctionalInterfacepublicinterfaceRunnable{publicabstractvoidrun();}Callable很多人都知道想在多线程中获取异步返回值结果一般是通过Callable和FutureTask接口配合实现的,但是很多人可能不知道Callable是依赖Runnable的run方法执行任务,然后通过FutureTask收集返回值结果,下面我们模拟写一个FutureTask代码,看看它是如何实现的。/***@authoryinfeng*@description自己实现futureTask,线程通信基于park/unpark*@since2022/1/921:32*/publicclassMyFutureTaskimplementsRunnable{Callablecallable;/***可调用的执行结果*/Tresult;/***任务执行状态*/Stringstate="new";/***存储等待消费者*/LinkedBlockingQueuewaiters=newLinkedBlockingQueue<>();publicMyFutureTask(Callablecallable){this.callable=callable;}@Overridepublicvoidrun(){try{result=callable.call();}catch(Exceptione){e.printStackTrace();}最后{state="end";}//任务执行完成后,通过unparking通知消费者System.out.println(Thread.currentThread().getName()+"生产者执行结束,通知消费者");while(true){Threadwaiter=waiters.poll();如果(服务员==null){休息;}LockSupport.unpark(服务员);}}/***park/unpark*/publicTget()throwsException{ThreadmainThread=Thread.currentThread();//塞入等待集合waiters.add(mainThread);//判断状态System.out.println(Thread.currentThread().getName()+"消费者进入等待");while(!"end".equals(state)){//阻塞等待任务执行完成通知LockSupport.park(mainThread);}返回结果;}}写个demo测试一下/***@authoryinfeng*@description*@since2022/1/921:32*/publicclassFutureTaskTest{publicstaticvoidmain(String[]args)throwsException{final我的未来任务;futureTask=newMyFutureTask<>(()->{Thread.sleep(5000);返回“任务完成888”;});新线程(futureTask).start();最终字符串结果=futureTask.get();System.out.println("结果:"+结果);//控制台打印如下://主消费者进入等待//Thread-0生产者执行完毕,通知消费者//结果:任务完成888}}可见我们的demo也运行正常,所以关键点就是Callable依赖Runnable的run方法来执行任务