java面试常问的Runnable和Callable的区别
Runnable
Runnable接口非常简单,就定义了一个方法run(), 实现Runnable接口的run方法就可以实现多线程
// 函数式接口 @FunctionalInterface public interface Runnable { public abstract void run(); }
Callable
可能很多人都知道要想在多线程中获取异步返回值结果一般是用Callable和FutureTask接口来实现,但可能很多人都不知道其实Callable是依赖于Runnable的run方法进行执行任务的,然后在通过FutureTask来收集返回值结果,下面咱们就自己模拟写一份FutureTask代码来看看是怎么实现的吧。
/** * @author yinfeng * @description 自己实现futureTask,基于park/unpark进行线程通讯 * @since 2022/1/9 21:32 */ public class MyFutureTask<T> implements Runnable { Callable<T> callable; /** * callable执行结果 */ T result; /** * task执行状态 */ String state = "new"; /** * 存储正在等待的消费者 */ LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>(); public MyFutureTask(Callable<T> callable) { this.callable = callable; } @Override public void run() { try { result = callable.call(); } catch (Exception e) { e.printStackTrace(); } finally { state = "end"; } // 任务执行完成后通过unpark通知消费者 System.out.println(Thread.currentThread().getName() + " 生产者执行结束,通知消费者"); while (true) { Thread waiter = waiters.poll(); if (waiter == null) { break; } LockSupport.unpark(waiter); } } /** * park / unpark */ public T get() throws Exception { Thread mainThread = Thread.currentThread(); // 塞入等待的集合中 waiters.add(mainThread); // 判断状态 System.out.println(Thread.currentThread().getName() + " 消费者进入等待"); while (!"end".equals(state)) { // 阻塞等待任务执行完成后通知 LockSupport.park(mainThread); } return result; } }
我们写个demo测试一下
/** * @author yinfeng * @description * @since 2022/1/9 21:32 */ public class FutureTaskTest { public static void main(String[] args) throws Exception { final MyFutureTask<String> futureTask = new MyFutureTask<>(() -> { Thread.sleep(5000); return "任务完成888"; }); new Thread(futureTask).start(); final String result = futureTask.get(); System.out.println("结果:"+result); // 控制台打印如下: // main 消费者进入等待 // Thread-0 生产者执行结束,通知消费者 // 结果:任务完成888 } }
可以看到我们的demo也是正常运行的,所以很关键的一点还是Callable是依赖于Runnable的run方法进行执行任务的
到此这篇关于java面试常问的Runnable和Callable的区别的文章就介绍到这了,更多相关java Runnable和Callable区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
- Java使用多线程批次查询大量数据(Callable返回数据)方式
- Java通过Callable实现多线程
- Java多线程中Callable和Future的解读
- Java中的Callable实现多线程详解
- Java使用Callable接口实现多线程的实例代码
- Java多线程实现之Callable详解
- Java中Runnable和Callable分别什么时候使用
- Java中Runnable与Callable接口的区别详解
- 详解Java中Callable和Future的区别
- Java使用Runnable和Callable实现多线程的区别详解
- Java并发教程之Callable和Future接口详解
- Java中callable的实现原理
相关文章
MybatisPlus EntityWrapper如何自定义SQL
这篇文章主要介绍了MybatisPlus EntityWrapper如何自定义SQL,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-03-03Spring Boot RestController接口输出到终端的操作代码
这篇文章主要介绍了Spring Boot RestController接口如何输出到终端,使用 HttpServletResponse 类,可以在使用curl执行 Spring Boot REST接口的同时,在控制台输出一些信息,给运维人员知道当前命令执行的状态,感兴趣的朋友跟随小编一起看看吧2023-09-09SpringBoot+Vue静态资源刷新后无法访问的问题解决方案
这篇文章主要介绍了SpringBoot+Vue静态资源刷新后无法访问的问题解决方案,文中通过代码示例和图文讲解的非常详细,对大家解决问题有一定的帮助,需要的朋友可以参考下2024-05-05springcloud整合gateway实现网关全局过滤器功能
本文主要介绍了springcloud整合gateway实现网关全局过滤器功能,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2022-02-02Java网络编程之URL+URLconnection使用方法示例
这篇文章主要介绍了Java网络编程之URL+URLconnection使用方法示例,还是比较不错的,这里分享给大家,供需要的朋友参考。2017-11-11
最新评论