java队列(Queue)使用总结

Queue一个先入先出(FIFO)的数据结构:

  1. 分为阻塞队列与非阻塞队:

    阻塞队列与非阻塞队的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,比如从队列中移除一个或者多个元素,或者完全清空队列。

    内置的不阻塞队列:
    *PriorityQueue(优先级队列)
    *ConcurrentLinkedQueue(基于链表的并发队列)(判断是否有元素可以使用isEmpty()方法,不要用size()>0)

    实现阻塞接口的:
    *ArrayBlockingQueue:(基于数组的并发阻塞队列)
    *LinkedBlockingQueue :(基于链表的FIFO阻塞队列)
    *PriorityBlockingQueue :(带优先级的无界阻塞队列)
    *DelayQueue :(延期阻塞队列)(阻塞队列实现了BlockingQueue接口)
    *SynchronousQueue :(并发同步阻塞队列)

  2. 阻塞队列操作:

    add:增加一个元索 , 如果队列已满,则抛出一个IIIegaISlabEepeplian异常  
    offer:添加一个元素并返回true,如果队列已满,则返回false
    put:添加一个元素,如果队列满,则阻塞

    remove:移除并返回队列头部的元素,如果队列为空,则抛出一个NoSuchElementException异常
    poll:移除并返问队列头部的元素, 如果队列为空,则返回null
    take:移除并返回队列头部的元素,如果队列为空,则阻塞

    element:返回队列头部的元素, 如果队列为空,则抛出一个NoSuchElementException异常
    peek:返回队列头部的元素,如果队列为空,则返回null

( 说明:如果是定长队列,元素没满的时候任何一个插入方法都可以,但是如果满了,add就会报错,offer不会报错,会返回false,put会阻塞等待( 类似wait() ),直到有空位立马插入。(remove,poll,take)同插入原理一样,peek()和element()方法仅仅查询头部元素,不会移除 )

  1. 生产者、消费者代码示例:
package com.example.demo.poolTest;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

class Producer implements Runnable{

	private ArrayBlockingQueue<Integer> queue;
	private boolean flag = true;
	private Integer count = 0;

	public Producer(ArrayBlockingQueue<Integer> queue) {
		this.queue = queue;
	}

	@Override
	public void run() {
		System.out.println("生产者启动成功!");
		while (flag) {
			count = count + 1;
			try {
				boolean offer = queue.offer(count);
				if(!offer){
					System.out.println("已经放满啦~");
				}else{
					System.out.println( Thread.currentThread().getName() + ":生产者放入" + this.count);
				}
				Thread.sleep(1000);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		System.out.println("生产者停止!");
	}

	public void stop() {
		this.flag = false;
	}
}

class Consumer implements Runnable{

	private ArrayBlockingQueue<Integer> queue;
	private boolean flag = true;

	public Consumer(ArrayBlockingQueue<Integer> queue) {
		this.queue = queue;
	}

	@Override
	public void run() {
		System.out.println("消费者启动成功!");
		while (flag) {
			try {
				Integer data = queue.poll(2, TimeUnit.SECONDS);
				if(data == null){
					flag = false;
					System.out.println("已经取完啦~");
				}else{
					System.out.println( Thread.currentThread().getName() + ":消费者取出" + data);
				}
				Thread.sleep(1000);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

public class testQueue {

	public static void main(String[] args) throws Exception{
		ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);
		Producer producer = new Producer(queue);
		Consumer consumer = new Consumer(queue);
		Thread producerThread = new Thread(producer);
		Thread consumerThread = new Thread(consumer);
		producerThread.start();
		consumerThread.start();
		Thread.sleep(5000);
		producer.stop();
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值