Java中的BlockingQueue系列

一、BlockingQueue
BlockingQueue是java.util.concurrent包下的一个接口,它是一个线程安全的队列,所以它最典型的用途就是生产者-消费者模式。

这里写图片描述

生产线程生产对象放入队列,如果队列放满,该线程就处于阻塞状态,直到消费线程从队列中取出对象进行消费。
消费线程从队列中取出对象进行消费,如果队列为空,该线程处于阻塞状态,直到生产线程生成一个新对象放入队列。

BlockingQueue的方法
方法总是分为三类:插入,删除,查看。
这里写图片描述

可以看到上面三类方法分四种不同行为:

  • Throws Exception: 如果操作无法立刻执行,就会抛出异常
  • Special Value: 如果执行的操作无法立刻执行,就会返回一个指定的值(通常为true和false)
  • Blocks: 如果执行的操作无法立刻执行,就会阻塞,直到该操作可以执行
  • Times Out: 如果执行的操作无法立刻执行,就会阻塞,并且设置有一个阻塞时间,如果在这个时间内还是不能执行到,就算超时,它会返回一个执行的值代表是否执行成功(通常为true和false)。

BlockingQueue的实现类

ArrayBlockingQueue
DelayQueue
LinkedBlockingQueue
PriorityBlockingQueue
SynchronousQueue

这里写图片描述

例子:

public class BlockingQueueExample {

    public static void main(String[] args) throws Exception {

        BlockingQueue queue = new ArrayBlockingQueue(1024);

        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);

        new Thread(producer).start();
        new Thread(consumer).start();

        Thread.sleep(4000);
    }
}

public class Producer implements Runnable{

    protected BlockingQueue queue = null;

    public Producer(BlockingQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            queue.put("1");
            Thread.sleep(1000);
            queue.put("2");
            Thread.sleep(1000);
            queue.put("3");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Consumer implements Runnable{

    protected BlockingQueue queue = null;

    public Consumer(BlockingQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            System.out.println(queue.take());
            System.out.println(queue.take());
            System.out.println(queue.take());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

下面来具体看看它的几个实现类:

二、ArrayBlockingQueue
从名字也可以看出,这个队列是使用一个数组来存放对象元素。

基本用法:

BlockingQueue queue = new ArrayBlockingQueue(1024);

queue.put("1");

Object object = queue.take();

三、DelayQueue
DelayQueue是一个延迟队列,用于放置实现了Delayed接口的对象,其中的对象只能在指定的延迟时间点上才能从队列中取走。

public interface Delayed extends Comparable<Delayed> {

 public long getDelay(TimeUnit timeUnit);

}

队列中的每个对象都必须实现这个接口,getDelay方法为延迟的时间,也就是该对象必须延迟指定的时间才能被取走。

TimeUnit是一个Enum类型,包括以下值:

DAYS
HOURS
MINUTES
SECONDS
MILLISECONDS
MICROSECONDS
NANOSECONDS

例子:

public class DelayQueueExample {

    public static void main(String[] args) {
        DelayQueue queue = new DelayQueue();

        Delayed element1 = new DelayedElement();

        queue.put(element1);

        Delayed element2 = queue.take();
    }
}

四、LinkedBlockingQueue

这个跟ArrayBlockingQueue类似,只是它的队列实现是链表。

例子:

BlockingQueue<String> unbounded = new LinkedBlockingQueue<String>();
BlockingQueue<String> bounded   = new LinkedBlockingQueue<String>(1024);

bounded.put("Value");

String value = bounded.take();

五、PriorityBlockingQueue

一个无界的阻塞队列,它里面存放的对象可以进行比较,并且具有优先级,它使用与类 PriorityQueue 相同的顺序规则,并且提供了阻塞检索的操作。

因为它里面存放的对象具有优先级,并且进行了优先级排序,所以所有的对象必须实现Comparable接口。

例子:

BlockingQueue queue   = new PriorityBlockingQueue();

//String implements java.lang.Comparable
queue.put("Value");

String value = queue.take();

六、SynchronousQueue

这个队列的特定就是他的队列里面只能存放一个对象,当一个线程放入一个对象之后就处于阻塞状态,等待另一个线程将对象取出之后,它才能接着放入对象。

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值