并发新构件之PriorityBlockingQueue:优先阻塞队列

PriorityBlockingQueue:优先阻塞队列;是带有优先级的阻塞队列,一个无界阻塞队列,它使用与类 PriorityQueue 相同的顺序规则,并且提供了阻塞获取操作。虽然此队列逻辑上是无界的,但是资源被耗尽时试图执行 add 操作也将失败(导致 OutOfMemoryError)。此类不允许使用 null 元素。依赖自然顺序的优先级队列也不允许插入不可比较的对象(这样做会导致抛出 ClassCastException)。

package com.houjun.current.newClassBank;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @Author: HouJun
 * @Date: 2019/10/18 8:31
 * @Description: 测试优先阻塞队列
 * @version: 1.0
 */
public class PriorityBlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService exec = Executors.newCachedThreadPool();
        PriorityBlockingQueue<Runnable> priorityBlockingQueue = new PriorityBlockingQueue<>();
        exec.execute(new PrioritizedTaskProducer(priorityBlockingQueue, exec));
//        TimeUnit.SECONDS.sleep(4);
        exec.execute(new PrioritizedTaskConsumer(priorityBlockingQueue));

    }
}

//可加入优先队列的对象,
class PrioritizedTask implements Runnable, Comparable<PrioritizedTask> {
    Random random = new Random(47);
    private static int counter = 0;
    private final int id = counter++;
    private final int priority;
    protected static List<PrioritizedTask> sequence = new ArrayList<>();

    public PrioritizedTask(int priority) {
        this.priority = priority;
        sequence.add(this);
    }

    @Override
    public void run() {
        try {
            TimeUnit.MILLISECONDS.sleep(random.nextInt(250));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(this);
    }

    @Override
    public String toString() {
        return String.format("[%1$-3d]", priority) + " Task " + id;
    }

    public String summary() {
        return "(" + id + " : " + priority + ")";
    }

    @Override//这样就是升序
    public int compareTo(PrioritizedTask o) {
        if (priority > o.priority)//这样就是升序
            return 1;
        if (priority < o.priority)//这样就是升序
            return -1;
        return 0;
    }
}

//生产者,向优先队列中添加对象
class PrioritizedTaskProducer implements Runnable {
    Random random = new Random(47);
    private Queue<Runnable> queue;
    private ExecutorService executorService;

    public PrioritizedTaskProducer(Queue<Runnable> queue, ExecutorService executorService) {
        this.queue = queue;
        this.executorService = executorService;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            queue.add(new PrioritizedTask(random.nextInt(10)));
            Thread.yield();
        }
        for (int i = 0; i < 10; i++) {
            try {
                TimeUnit.MILLISECONDS.sleep(250);
                queue.add(new PrioritizedTask(20));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int i = 0; i < 10; i++) {
            queue.add(new PrioritizedTask(i));
        }
        System.out.println("Finished PrioritizedTaskProducer");
    }
}

//消费者,取出优先队列的类
class PrioritizedTaskConsumer implements Runnable {
    private PriorityBlockingQueue<Runnable> queue;

    public PrioritizedTaskConsumer(PriorityBlockingQueue<Runnable> queue) {
        this.queue = queue;
        System.out.println("队列中的元素个数" + queue.size());
    }

    @Override
    public void run() {
        while (!Thread.interrupted()) {
            try {
                queue.take().run();//拿出优先级队列中的任务,并运行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Finished PrioritizedTaskConsumer");
    }
}

原文地址:https://www.cnblogs.com/houj/p/11696938.html

时间: 2024-11-02 19:29:08

并发新构件之PriorityBlockingQueue:优先阻塞队列的相关文章

Java并发新构件之PriorityBlockingQueue

An unbounded blocking queue that uses the same ordering rules as class PriorityQueue and supplies blocking retrieval operations. While this queue is logically unbounded, attempted additions may fail due to resource exhaustion (causing OutOfMemoryErro

java并发编程(十八)阻塞队列和阻塞栈

阻塞队列 阻塞队列是Java 5并发新特性中的内容,阻塞队列的接口是java.util.concurrent.BlockingQueue,它有多个实现类:ArrayBlockingQueue.DelayQueue.LinkedBlockingQueue.PriorityBlockingQueue.SynchronousQueue等,用法大同小异,具体可查看JDK文档,这里简单举例看下ArrayBlockingQueue,它实现了一个有界队列,当队列满时,便会阻塞等待,直到有元素出队,后续的元素才

Java并发编程(十一):阻塞队列(转载)

本文转载自:http://www.cnblogs.com/dolphin0520/p/3932906.html 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList),这些工具都为我们编写多线程程序提供了很大的方便.今天我们来讨论另外一类容器:阻塞队列. 在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现

并发容器(三)非阻塞队列的并发容器

??本文将介绍除了阻塞队列外的并发容器: ConcurrentHashMap.CopyOnWriteArrayList.CopyOnWriteArraySet.ConcurrentSkipListMap.ConcurrentSkipListSet.ConcurrentLinkedQueue: 1. CopyOnWriteArrayList 是 ArrayList 的线程安全的实现,同时也可用于代替 Vector .底层实现是一个数组,其中所有可变操作(add.set 等等)都是通过对底层数组进行

【死磕Java并发】-----J.U.C之阻塞队列:SynchronousQueue

[注]:SynchronousQueue实现算法看的晕乎乎的,写了好久才写完,如果当中有什么错误之处,忘各位指正 作为BlockingQueue中的一员,SynchronousQueue与其他BlockingQueue有着不同特性: 没有容量.与其他BlockingQueue不同,是一个不存储元素的BlockingQueue.每一个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然. 因为没有容量,所以对应 peek, contains, clear, isEmpty - 等方

Java并发新构件之DelayQueue

DelayQueue主要用于放置实现了Delay接口的对象,其中的对象只能在其时刻到期时才能从队列中取走.这种队列是有序的,即对头的延迟到期时间最短.如果没有任何延迟到期,那么久不会有任何头元素,并且poll()将返回null(正因为这样,你不能将null放置到这种队列中) 下面是一个示例,其中的Delayed对象自身就是人物,而DelayedTaskConsumer将最"紧急"的任务从队列中取出来,然后运行它: import java.util.ArrayList; import j

Java并发编程(十一)-- 阻塞队列

在介绍Java的阻塞队列之前,我们简单介绍一下队列. 队列 队列是一种数据结构.它有两个基本操作:在队列尾部加人一个元素,和从队列头部移除一个元素就是说,队列以一种先进先出的方式管理数据,如果你试图向一个已经满了的阻塞队列中添加一个元素或者是从一个空的阻塞队列中移除一个元索,将导致线程阻塞.在多线程进行合作时,阻塞队列是很有用的工具.工作者线程可以定期地把中间结果存到阻塞队列中而其他工作者线线程把中间结果取出并在将来修改它们.队列会自动平衡负载.如果第一个线程集运行得比第二个慢,则第二个 线程集

java多线程(九)阻塞队列

转载请注明出处:http://blog.csdn.net/xingjiarong/article/details/48005091 前边的博客中我们介绍了如果用对象锁和条件锁以及更加方便的synchronized关键字来实现多线程的同步和互斥,也许你会觉得使用synchronized关键字已经非常方便了,但是使用者必须真正的理解synchronized的用法,而且要有一定的多线程的编程的经验,否则很难做到全面的考虑问题而造成意想不到的问题.其实在java中还有比synchronized关键字更加

阻塞队列-BlockingQueue

适用场景 阻塞队列主要用在生产者/消费者的场景,下面这幅图展示了一个线程生产.一个线程消费的场景: 负责生产的线程不断的制造新对象并插入到阻塞队列中,直到达到这个队列的上限值.队列达到上限值之后生产线程将会被阻塞,直到消费的线程对这个队列进行消费.同理,负责消费的线程不断的从队列中消费对象,直到这个队列为空,当队列为空时,消费线程将会被阻塞,除非队列中有新的对象被插入. 原文地址:https://www.cnblogs.com/517cn/p/10868141.html