队列 之 非阻塞式队列与阻塞式队列

队列主要遵循先进先出,后进后出的原则。

阻塞式队列与非阻塞式队列

区别:
**阻塞式队列:**入列时如果超出队列总数,会等待(阻塞)。出列时如果获取队列为空,也会等待(阻塞)。效率低。能够防止队列容器溢出,防止丢失数据。
**非阻塞式队列:**入列时如果超出队列总数直接报错。效率高。

并发队列-ConcurrentLinkedQueue(非阻塞式队列)

ConcurrentLinkedQueue是无界队列。

ConcurrentLinkedQeque queue = new ConcurrentLinkedQeque();
queue .offer("Lucy");
queue .offer("Jimmy");
queue .offer("James");
//从头获取元素,删除该元素
System.out.println(queue .poll());
//从头获取元素,不刪除该元素
System.out.println(queue .peek());
//获取总长度
System.out.println(queue .size());

BlockingQueue(阻塞式队列)

ArrayBlockingQueue
ArrayBlockingQueue是一个有边界的阻塞队列,它的内部实现是一个数组。有边界的意思是它的容量是有限的,我们必须在其初始化的时候指定它的容量大小,容量大小一旦指定就不可改变。

<String> arrays = new ArrayBlockingQueue<String>(3);
arrays.add("李四");//添加非阻塞式队列
arrays.add("王五");
arrays.add("李四");
// 添加阻塞队列
arrays.offer("张三", 3, TimeUnit.SECONDS);//添加阻塞式队列,等待3秒

LinkedBlockingQueue
LinkedBlockingQueue阻塞队列大小的配置是可选的,如果我们初始化时指定一个大小,它就是有边界的,如果不指定,它就是无边界的。说是无边界,其实是采用了默认大小为Integer.MAX_VALUE的容量 。它的内部实现是一个链表。

PriorityBlockingQueue
PriorityBlockingQueue是一个没有边界的队列,它的排序规则和 java.util.PriorityQueue一样。需要注
意,PriorityBlockingQueue中允许插入null对象。
所有插入PriorityBlockingQueue的对象必须实现 java.lang.Comparable接口,队列优先级的排序规则就 是按照我们对这个接口的实现来定义的。
另外,我们可以从PriorityBlockingQueue获得一个迭代器Iterator,但这个迭代器并不保证按照优先级顺 序进行迭代。

SynchronousQueue
SynchronousQueue队列内部仅允许容纳一个元素。当一个线程插入一个元素后会被阻塞,除非这个元素被另一个线程消费。

模拟生产者/消费者


import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 生产者
 */
class ProduderThread implements Runnable{
    private BlockingQueue<String> blockingQueue;
    private AtomicInteger count = new AtomicInteger();
    private volatile boolean FLAG = true;

    public ProduderThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        System.out.println("生成者启动...");
        while (FLAG){
            String data = count.incrementAndGet() + "";
            try {
                boolean res = blockingQueue.offer(data,2,TimeUnit.SECONDS);
                if(res){
                    System.out.println(Thread.currentThread().getName()+"生产队列"+data+"成功");
                }else{
                    System.out.println(Thread.currentThread().getName()+"生产队列"+data+"失败");
                }
                Thread.sleep(1000);
            }catch (Exception e){
				e.printStackTrace();
            }
        }
    }

    public void stop(){
        FLAG = false;
    }
}

/**
 * 消费者
 */
class ConsumerThread implements Runnable{
    private BlockingQueue<String> blockingQueue;
    private volatile boolean FLAG = true;

    public ConsumerThread(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public void run() {
        System.out.println("消费者启动...");
        while (FLAG){
            try {
                String data = blockingQueue.poll(2,TimeUnit.SECONDS);
                if(data == null){
                    FLAG = false;
                    System.out.println(Thread.currentThread().getName()+"消费者获取数据超时");
                    return;
                }
                System.out.println(Thread.currentThread().getName()+"消费者获取数据成功,data:"+data);
            }catch (Exception e){
				e.printStackTrace();
            }
        }
    }

    public void stop(){
        FLAG = false;
    }
}

public class BlockingQueueTest {

    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new LinkedBlockingQueue(3);
        ProduderThread produderThread = new ProduderThread(blockingQueue);
        new Thread(produderThread).start();
        new Thread(new ConsumerThread(blockingQueue)).start();

        try{
            Thread.sleep(20*1000);
            produderThread.stop();
        }catch (Exception e){
			e.printStackTrace();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值