目录
91.BlockQueue实现例子?
92.什么是BlockingDequeue?适合用在什么样的场景?
93.BlockingDeque与BlockingQueue有何关系,请对比下他们的方法?
94.BlockingDeque大家族有哪些?
96.FutureTask用来解决什么问题的?为什么会出现?
97.FutureTask类结构关系是怎么样的?
98.FutureTask的线程安全是由什么保证的?
99.FutureTask通常怎么用?举例说明。
100.为什么要有线程池?
91.BlockQueue实现例子?
这里是一个Java中使用BlockingQueue的示例。本示例使用的是BlockingQueue接口的ArrayBlackingQueue实现。
首先,BlockingQueueExample类分别在两个独立的线程中启动了一个Producer和一个Consumer。Producer向一个共享的BlockingQueue中注入字符串,而Consumer则会从中把他们拿出来。
以下是Producer类。注意他在每次put()调用时如何休眠一秒钟的。这将导致Consumer在等待队列中对象的时候发生阻塞。
以下是Consumer类。他只是把对象从队列中抽取出来,然后将他们打印到System.out。
92.什么是BlockingDequeue?适合用在什么样的场景?
java.util.concurrent包里的BlockingDeque接口表示一个线程放入和提取实例的双端队列。
BlockingDeque类是一个双端队列,在不能插入元素时,他将阻塞住试图插入元素的线程;在不能抽取元素时,他将阻塞住试图抽取的线程。
deque(双端队列)是”Double Ended Queue“的缩写。因此,双端队列是一个你可以从任意一端插入或者抽取元素的队列。
在线程既是一个队列的生产者又是这个队列的消费者的时候可以使用到BlockingDeque。如果生产者线程需要在队列的两端都可以插入数据,消费者线程需要在队列的两端都可以移除数据,这个时候也可以使用BlockingDeque。
BlockingDeque图解:
93.BlockingDeque与BlockingQueue有何关系,请对比下他们的方法?
BlockingDeque接口继承自BlockingQueue接口。这就意味着你可以像使用一个BlockingQueue那样使用BlockingDeque。如果你这么干的话,各种插入方法将会把新元素添加到双端队列的尾端,而移除方法将会把双端队列的首端元素移除。正如BlockingQueue接口的插入和移除方法一样。
以下是BlockingDeque对BlockingQueue接口方法的具体内部实现:
94.BlockingDeque大家族有哪些?
LinkedBlockingDeque是一个双端队列,在他为空的时候,一个试图从中抽取数据线程将会阻塞,无论该线程是试图从哪一端抽取数据。
95.BlockingDeque实现例子?
既然BlockingDeque是一个接口,那么你想要使用他的话就得使用他的众多实现类的其中一个。
java.util.concurrent包提供了以下BlockingDeque接口的实现类:LinkedBlockingDeque。
以下是如何使用BlockingDeque方法的一个简短代码示例:
96.FutureTask用来解决什么问题的?为什么会出现?
FutureTask为Future提供了基础实现,如获取任务执行结果(get)和取消任务(cancel)等。如果任务尚未完成,获取任务执行结果将会阻塞。一旦执行结束,任务就不能被重启或者取消(除非使用runAndReset执行计算)。FutureTask用来封装Callable和Runnable,也可以作为一个任务提交到线程池执行。除了作为一个独立的类之外,此类也提供了一些功能性函数供我们创建自定义Task类使用。FutureTask的线程安全由CAS来保证。
97.FutureTask类结构关系是怎么样的?
可以看到,FutureTask实现了RunnableFuture接口,则RunnableFuture接口继承了Runnable接口和Future接口,所以FutureTask既能当做一个Runnable直接被Thread执行,也能作为Future用来得到Callable的计算结果。
98.FutureTask的线程安全是由什么保证的?
由CAS保证的。
99.FutureTask通常怎么用?举例说明。
100.为什么要有线程池?
线程池能够对线程进行统一分配,调优和监控:
降低资源消耗(线程无限制的创建,然后使用完毕后销毁)
提高响应速度
提高线程的可管理型=性