天天看点

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

文章目录

  • ​​生产者消费者-阻塞队列版本​​
  • ​​Callable接口​​

生产者消费者-阻塞队列版本

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

关于上面的代码,多线程环境下,调用资源类,关键变量要加volatile,原子类变量不用加,因为源码里面的包装类加了,我们在这里使用就不用加。如果是想做适配性很好的代码设计,要适配所有的阻塞队列的子类,就不能在方法里确定,而是要让调用者把具体的实现传进来,也就是面向接口的编程。所谓的高手都是传接口,绝对不是传类!

关于这里的代码,写,要足够的抽象,也就是传接口,要查,要利用反射,把具体的类的实现记一下日志。

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍
11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

这个地方消费线程flag=false的行为,我不是很认同,消费线程取不到不应该停下吧,个人认为这个逻辑不对。

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

测试代码:

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

5s后叫停。

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

执行结果:

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

总结一下阻塞队列版本的线程通信:

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

Callable接口

多线程的方式:

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

两者的区别:1.runable接口没有返回值。但另一个是有的(适用于带返回值的线程工作流)。2.接口实现方法不一样,一个run,一个call、3

那么callable接口怎么在项目中使用呢?如果只用thread去接收callable接口该如何处理呢?目前thread只能接受runable接口。

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

如果一个类即实现了runable,也实现了callable,传这一个类就可以变相的适配了,这就是适配器模式的使用。

JDK给我们提供了,他就是futureTask接口。本身是runable接口的子类,传进去callable接口,就可以实现适配了。

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

实际使用:

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍
11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

运行结果:

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

如何获得callable的返回值呢?api提供了,如下:

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

这种用法在批次任务中,经常会出现。比如每一笔帐都要有返回值。

为什么callable会出现:并发,异步,导致callable出来了。

以前没有callable,编程的感觉就是一根签子通到底,冰糖葫芦串,顺序执行。如果节点占用时间过长,那就只能等着。

但是有了多线程之后,就可以用callable接口,把可以拆分的任务拆分出去并行执行,最后结果汇总。

多线程牛逼的不是锁,而是控制.

技巧:futureTask的get方法,建议放在最后执行。因为一旦get的那个任务还没执行完成,那么就会阻塞在这,所以get方法一般放在最后。

那么什么时候汇总呢?可以用自旋锁的思想,while一直去主动确认。

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

问题:如果一个futureTask被两个线程执行了2次,那么相关方法会如何执行?

结果是,只会执行一遍,因为一个计算过程算一遍就对了,不会算两遍。

11.互联网大厂高频面试题-阻塞队列(下)+callable介绍

继续阅读