【正确答案】
A、B、D
【答案解析】 在Java多线程应用中,队列的使用频率很高。队列是一种先进先出的数据结构,它有两个基本操作:在队列尾部添加一个元素以及从队列头部移除一个元素。如果向一个已经满了的阻塞队列中添加一个元素或者从一个空的阻塞队列中移除一个元索,都将导致线程阻塞。
在讲解后面的知识之前,首先对阻塞与非阻塞进行分析。什么是阻塞?什么是非阻塞?阻塞与非阻塞关注的是程序在等待调用结果(消息、返回值)时的状态。阻塞调用指的是在调用结果返回之前,当前线程会被挂起,调用线程只有在得到结果之后才会返回,而非阻塞调用指的是在不能立刻得到结果之前,该调用不会阻塞当前线程。举个简单例子加以说明,小王打电话给书店老板老张,询问书店是否有《Java程序员面试笔试真题与解析》这本书,如果是阻塞式调用,小王会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,小王会不管老张有没有告诉自己,小王先做自己的事情了,当然,小王也要偶尔过来检查一下老张有没有返回结果。
Java语言提供的线程安全的队列可以分为阻塞队列和非阻塞队列,其中,阻塞队列的典型例子是LinkedBlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在应用中要根据实际需要选用阻塞队列或者非阻塞队列。以下将分别对这两种队列进行介绍。
LinkedBlockingQueue是一个线程安全的阻塞队列,实现了先进先出等特性,一般用在生产者和消费者模型的开发中。它的底层采用链表的方式来实现,采用锁机制来实现多线程同步,提供了一个构造方法来指定队列的大小,如果不指定队列的大小,队列的默认大小为Intege.MAX_VKLUE(它表示int类型能够表示的最大值,值为2^31-1的常量)。
ConcurrentLinkedQueue是一个基于链表实现的、无界的、线程安全的队列。无界表示它没有提供一个构造方法来指定队列的大小。为了能提高并发量,它通过使用更加细粒度锁的机制使得在多线程环境下不需要对所有的数据进行锁定从而提高运行效率。
通过以上分析可知,选项A、选项B与选项D正确。