使用 阻塞队列 的生产者消费者模式
public class Pattern {
BlockingQueue<String> chanel = new ArrayBlockingQueue<String>(10);
// 消费者
public synchronize String take() throws Exception{
String take = chanel.take();
if (take==null){
return null;
}
return take;
}
// 生产者
public synchronize void put(String s) throws Exception{
chanel.put(s);
}
public static void main(String[] args) {
}
}
ArrayBlockingQueue,LinkBlockingQueue,SynchronousQueue
ArrayBlockingQueue :
对于他内部的take,put 都是使用相同一把锁,在并发量相对较高的情况下,会造成锁的争用性高,导致较多的上下文切换。其内存空间是预先分配的,操作并不会增加垃圾回收的负担。
LinkBlockingQueue:
他内部的 put,take操作使用的是两个锁,这降低了锁争用。但有一点,其内部的存储空间采用的是一个链表,所需的存储空间是动态分配的,操作可能会增加垃圾回收的负担。
SynchronousQueue:
内部并不维护用于存储队列元素的存储空间。他的执行就等同与他内部只有一个空间,一旦有生产者生产以后就等待消费者取出,否则进入阻塞状态。
选择:
LinkBlockingQueue 适合在生产者与消费者并发程度比较大的情况下进行使用。
ArrayBlockingQueue 适合在生产者与消费者之间并发程度比较低的情况下使用。
SynchronousQueue 适合在消费者的处理能力和生产者的处理能力相差不大的情况下使用。