BlockingQueue

插入方法

  1. boolean add(E e);把E加到BlockingQueue里,如果可以容纳则返回true,否则抛出异常。
  2. boolean offer(E e);把E加到BlockingQueue里,如果可以容纳则返回true,否则返回false。
  3. void put(E e) throws InterruptedException;把E加到BlockingQueue里,如果没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续。

读取

  1. E poll(time);取走BlockingQueue里排在首位的对象,若不能立即取出,可以等到参数规定的时间,取不到时候返回null。
  2. take()取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态,直到有新的对象被加入。

其他

  1. int remainingCapacity();返回队列剩余容量,在队列插入或获取时可能数据不准。
  2. boolean remove(Object o);从队列移除元素,如果存在则移除一个或更多,队列改变了返回true。
  3. public boolean contains(Object o);查看队列里是否存在这个元素,存在返回true。
  4. int drainTo(Collection<? super E> c);移除此队列中所有可用的元素,并把他们添加到指定的collection中。
  5. int drainTo(Collection<? super E> c, int maxElements);和上面方法一样,指定了移动的数量。

具体实现类

  1. ArrayBlockingQueue:一个由数组支持的有界阻塞队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小,其所含的对象是以先入先出顺序排序的。
  2. LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数生成的BlockingQueue。有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定,其所含的对象是以先入先出顺序排序的。
    LinkedBlockingQueue可指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列为空的时候会被阻塞,直到队列成员被放进来。

区别:他们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能可预见性低于ArrayBlockingQueue.

例子

Producer

package org.shareing.myBlockingQueue;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

public class Producer implements Runnable {

    BlockingQueue<String> queue;

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

    @Override
    public void run() {
        try {
            Thread.sleep(new Random().nextInt(10));
            System.out.println("I have made a product:"+Thread.currentThread().getName());
            String temp="A Product,生产线程,"+Thread.currentThread().getName();
            queue.put(temp);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

Consumer

package org.shareing.myBlockingQueue;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable {
    BlockingQueue<String> queue;

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

    @Override
    public void run() {
        try {
            Thread.sleep(new Random().nextInt(10));
            String name = Thread.currentThread().getName();
            System.out.println(name);
            //如果队列为空会阻塞当前线程
            String take = queue.take();
            System.out.println(name+"进行消费"+take);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Test

package org.shareing.myBlockingQueue;

import java.util.concurrent.LinkedBlockingDeque;

public class Test {
    public static void main(String[] args) {
        LinkedBlockingDeque<String> queue = new LinkedBlockingDeque<>(2);
        Consumer consumer = new Consumer(queue);
        Producer producer = new Producer(queue);
        for (int i = 0; i < 3; i++) {
            new Thread(producer,"Producer"+(i+1)).start();
        }
        for (int i = 0; i < 5; i++) {
            new Thread(consumer,"Consumer"+(i+1)).start();
        }
    }
}

运行结果:

Consumer1
I have made a product:Producer1
I have made a product:Producer3
Consumer1进行消费A Product,生产线程,Producer1
Consumer3
I have made a product:Producer2
Consumer3进行消费A Product,生产线程,Producer3
Consumer5
Consumer2
Consumer5进行消费A Product,生产线程,Producer2
Consumer4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值