欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java队列(Queue)使用总结

程序员文章站 2024-03-18 11:30:22
...

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();
	}

}
相关标签: java基础