BlockQueue 是什么?

本文内容如有错误、不足之处,欢迎技术爱好者们一同探讨,在本文下面讨论区留言,感谢。

简述

阻塞队列:当线程队列是空时,从队列中获取元素的操作将会被阻塞;当线程队列是满时,往队列里添加元素的操作将会被阻塞。

Java 5 开始出现存在 java.util.concurrent 包下,阻塞队列是一个队列,当尝试从队列中出队并且队列为空时,或者尝试将项目入队并且队列已满时,它将阻塞。尝试从空队列中出队的线程被阻止,直到其他线程将一个项目插入队列中为止。尝试使一个项目进入完整队列的线程被阻塞,直到某个其他线程在队列中腾出空间为止,方法是使一个或多个项目出队或完全清除队列。

原理

原理示意图片:
图片地址:http://tutorials.jenkov.com/java-concurrency/blocking-queues.html

在这里插入图片描述
下面是一个简单的BlockQueue的实现:

public class BlockingQueue {
  private List queue = new LinkedList();
  private int  limit = 10;
  public BlockingQueue(int limit){
    this.limit = limit;
  }
  
  public synchronized void enqueue(Object item)throws InterruptedException  {
    while(this.queue.size() == this.limit) {
      wait();
    }
    if(this.queue.size() == 0) {
      notifyAll();
    }
    this.queue.add(item);
  }
  
  public synchronized Object dequeue() throws InterruptedException{
    while(this.queue.size() == 0){
      wait();
    }
    if(this.queue.size() == this.limit){
      notifyAll();
    }
    return this.queue.remove(0);
  }
}

操作代码:

// 调用 BlockingQueue 方法的Java程序演示
  
import java.util.concurrent.*; 
import java.util.*; 
  
public class GFG { 
    public static void main(String[] args) 
        throws InterruptedException 
    { 
  
        // ArrayBlockingQueue 的边界大小
        int capacity = 5; 
  
        // 创建 ArrayBlockingQueue 
        ArrayBlockingQueue<String>  queue = new ArrayBlockingQueue<String>(capacity); 
  
        // 使用put()方法添加元素 
        queue.put("StarWars"); 
        queue.put("SuperMan"); 
        queue.put("Flash"); 
        queue.put("BatMan"); 
        queue.put("Avengers"); 
  
        // 打印队列
        System.out.println("queue contains "+ queue); 
  
        // 移除一些元素
        queue.remove(); 
        queue.remove(); 
		queue.put("CaptainAmerica"); 
        queue.put("Thor"); 
  
        System.out.println("queue contains " + queue); 
    } 
} 

输出结果:

queue contains [StarWars, SuperMan, Flash, BatMan, Avengers]
queue contains [Flash, BatMan, Avengers, CaptainAmerica, Thor]
操作

BlockingQueue方法有四种形式,它们以不同的方式处理操作,这些操作可能无法满足开发需求,但将来可能会满足:第一种抛出异常,第二种返回特殊值( null或false,具体取决于操作),第三个块将无限期地阻塞当前线程,直到操作成功为止;第四个块仅在给定的最大时间限制内超时。

下表总结了这些方法:

方法类型抛出异常特殊值阻塞超时
插入add(e)offer(e)put(e)offer(e,time,unit)
移除remove()poll()take()poll(time,unit)
检查element()peek()

这4种不同的行为集意味着:

  • 引发异常:如果无法立即进行尝试的操作,则会引发异常。
  • 特殊值:如果无法立即尝试操作,则会返回一个特殊值(通常为true / false)。
  • 阻塞:如果无法立即进行尝试的操作,则该方法调用将一直阻塞直到可行为止。
  • 超时:如果无法立即进行尝试的操作,则该方法调用将一直阻塞直到成功,但等待时间不得长于给定的超时。返回一个特殊值,告诉操作是否成功(通常为true / false)。

下面是一个生产者消费者的案例使用BlockQueue:

class Producer implements Runnable {
   private final BlockingQueue queue;
   Producer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while (true) { queue.put(produce()); }
     } catch (InterruptedException ex) { ... handle ...}
   }
   Object produce() { ... }
 }

 class Consumer implements Runnable {
   private final BlockingQueue queue;
   Consumer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while (true) { consume(queue.take()); }
     } catch (InterruptedException ex) { ... handle ...}
   }
   void consume(Object x) { ... }
 }

 class Setup {
   void main() {
     BlockingQueue q = new SomeQueueImplementation();
     Producer p = new Producer(q);
     Consumer c1 = new Consumer(q);
     Consumer c2 = new Consumer(q);
     new Thread(p).start();
     new Thread(c1).start();
     new Thread(c2).start();
   }
 }
参考资料

Blocking Queues

Interface BlockingQueue

Java BlockingQueue

BlockingQueue Interface in Java

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值