阻塞队列
What?
当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞;

Why?
- .阻塞队列不用手动控制线程什么时候该被阻塞,什么时候该被唤醒,简化了操作。
- 防止队列容器溢出,防止数据丢失。
分类
Collection–>Queue–>BlockingQueue–>7个实现类
- ArrayBlockingQueue: 由数组结构组成的有界阻塞队列
- LinkedBlockingQueue: 由链表结构组成的有界阻塞队列。
- PriorityBlockingQueue: 支持优先级排序的无界阻塞队列。
- DelayQueue: 使用优先级队列实现的延迟无界阻塞队列。
- SynchronousQueue: 单个元素的队列。
- LinkedTransferQueue: 由链表组成的无界阻塞队列。
- LinkedBlockingDeque: 有链表组成的双向阻塞队列。
生产者-消费者实例
使用BlockingQueue模拟生产者与消费者
- 抛出异常是指当队列满时,再次插入会抛出异常
- 返回布尔是指当队列满时,再次插入会返回false
- 阻塞是指当队列满时,再次插入会被阻塞,直到队列取出一个元素,才能插入
- 超时是指当一个时限过后,才会插入或者取出。

/**
* 生产者
*/
class ProductDemo implements Runnable{
//阻塞队列中
private BlockingQueue blockingQueue;
private volatile Boolean flag=true;
AtomicInteger atomicInteger=new AtomicInteger();
public ProductDemo (BlockingQueue<String> blockingQueue){
this.blockingQueue=blockingQueue;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"当前线程生产者开始运行=====");
try {
while (flag){
String data=atomicInteger.incrementAndGet()+"";
//生产者往阻塞队列中放数据
Boolean result= blockingQueue.offer(data,2, TimeUnit.SECONDS);
if(result){
System.out.println(Thread.currentThread().getName()+"当前线程生产者,生产的数据========"+data+"成功");
}else{
System.out.println(Thread.currentThread().getName()+"当前线程生产者,生产的数据========"+data+"失败");
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+"当前线程生产者运行结束=====");
}
}
public void stop(){
flag=false;
}
}
/**
* 消费者
*/
class ConsumerDemo implements Runnable{
private BlockingQueue blockingQueue;
private volatile Boolean flag=true;
public ConsumerDemo(BlockingQueue<String> blockingQueue){
this.blockingQueue=blockingQueue;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"当前线程消费者运行开始===========");
try {
while (flag){
//生产者从阻塞队列中获取数据
Object result= blockingQueue.poll(2,TimeUnit.SECONDS);
if(result ==null || result==""){
flag=false;
System.out.println(Thread.currentThread().getName()+"当前线程消费者,队列中没有数据");
return;
}
System.out.println(Thread.currentThread().getName()+"当前线程消费者,从队列中获取数据=="+result);
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+"当前线程消费者运行结束===========");
}
}
}
public class Demo{
public static void main(String[]args){
BlockingQueue<String> blockingQueue=new LinkedBlockingQueue<String>();
ProductDemo productDemo=new ProductDemo(blockingQueue);
ConsumerDemo consumerDemo=new ConsumerDemo(blockingQueue);
Thread t1=new Thread(productDemo);
Thread t2= new Thread(consumerDemo);
t1.start();
t2.start();
try {
Thread.sleep(10 *1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
productDemo.stop();
}
}

733

被折叠的 条评论
为什么被折叠?



