队列
8、缓冲队列
缓冲队列接口BlockingQueue,继承了Queue接口。
实现类:LinkedBlockingDeque
ArrayBlockingQueue
PriorityBlockingQueue
LinkedBlockingDeque大小不定的BlockingQueue若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定。其所含的对象是以FIFO顺序排序的。
ArrayBlockingQueue规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小,其所含的对象是以FIFO排序的。
PriorityBlockingQueue类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是一句对象的自然排序或者其构造函数的Comparator决定的顺序。
/**
* 测试阻塞队列
* offer()插入
* pull()拉出
*/
public class Demo01 {
public static void main(String[] args) {
//对空队列的拉出,发出I/O阻塞
final BlockingQueue<String> queue =
new LinkedBlockingDeque<String>(4);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
//尝试将数据写入到队列,如果不成功I/O阻塞等5秒,
5秒内一直尝试忘队列中插入,5秒之后还是满的,则返回false
queue.offer("HI",5,TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
//从队列中获取数据,如果没有数据就I/O阻塞(block)等5秒
//5秒内一直尝试着取数据,取到了返回,5秒还是没有数据,返回null
try {
String str = queue.poll(5, TimeUnit.SECONDS);
System.out.println(str);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
9、双缓冲队列
传统队列是生产者线程和消费者线程从同一个队列中存取数据,必然需要互斥访问,在互相同步等待中浪费了宝贵的时间,使队列吞吐量受影响。
双缓冲队使用两个队列,将读写分离,一个队列专门用来读,另一个专门用来写,当读队列空或写 队列满时将两个队列互换。这里为了保证队列的读写顺序,当读队列为空且写队列不为空时候才允许两个队列互换。
经过测试性能较JDK自带的queue的确有不小提高。