java 多线程阻塞队列 与 阻塞方法与和非阻塞方法
Queue是什么
队列,是一种数据结构。除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的。无论使用哪种排序方式,队列的头都是调用remove()或poll()移除元素的。在FIFO队列中,所有新元素都插入队列的末尾。队列都是线程安全的,内部已经实现安全措施,不用我们担心
Queue中的方法
Queue中的方法不难理解,6个,每2对是一个也就是总共3对。看一下JDK API就知道了:

注意一点就好,Queue通常不允许插入Null,尽管某些实现(比如LinkedList)是允许的,但是也不建议。
ArrayBlockingQueue:基于数组实现的一个阻塞队列,在创建ArrayBlockingQueue对象时必须制定容量大小。并且可以指定公平性与非公平性,默认情况下为非公平的,即不保证等待时间最长的队列最优先能够访问队列。
LinkedBlockingQueue:基于链表实现的一个阻塞队列,在创建LinkedBlockingQueue对象时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。
PriorityBlockingQueue:以上2种队列都是先进先出队列,而PriorityBlockingQueue却不是,它会按照元素的优先级对元素进行排序,按照优先级顺序出队,每次出队的元素都是优先级最高的元素。注意,此阻塞队列为无界阻塞队列,即容量没有上限(通过源码就可以知道,它没有容器满的信号标志),前面2种都是有界队列。
DelayQueue:基于PriorityQueue,一种延时阻塞队列,DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。DelayQueue也是一个无界队列,因此往队列中插入数据的操作(生产者)永远不会被阻塞,而只有获取数据的操作(消费者)才会被阻塞。
注意:
1、必须要使用take()方法在获取的时候达成阻塞结果
2、使用poll()方法将产生非阻塞效果
public class ArrayBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {private static final long serialVersionUID = -817911632652898426L;/** The queued items */private final E[] items;/** items index for next take, poll or remove */private int takeIndex;/** items index for next put, offer, or add. */private int putIndex;/** Number of items in the queue */private int count;/** Concurrency control uses the classic two-condition algorithm* found in any textbook.*//** Main lock guarding all access */private final ReentrantLock lock;/** Condition for waiting takes */private final Condition notEmpty;/** Condition for waiting puts */private final Condition notFull;}
public ArrayBlockingQueue(int capacity) {}public ArrayBlockingQueue(int capacity, boolean fair) {}public ArrayBlockingQueue(int capacity, boolean fair,Collection<? extends E> c) {}
public void put(E e) throws InterruptedException {if (e == null) throw new NullPointerException();final E[] items = this.items;final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {try {while (count == items.length)notFull.await();} catch (InterruptedException ie) {notFull.signal(); // propagate to non-interrupted threadthrow ie;}insert(e);} finally {lock.unlock();}}
private void insert(E x) {items[putIndex] = x;putIndex = inc(putIndex);++count;notEmpty.signal();}
public E take() throws InterruptedException {final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {try {while (count == 0)notEmpty.await();} catch (InterruptedException ie) {notEmpty.signal(); // propagate to non-interrupted threadthrow ie;}E x = extract();return x;} finally {lock.unlock();}}
private E extract() {final E[] items = this.items;E x = items[takeIndex];items[takeIndex] = null;takeIndex = inc(takeIndex);--count;notFull.signal();return x;}
public class Test {private int queueSize = 10;private PriorityQueue<Integer> queue = new PriorityQueue<Integer>(queueSize);public static void main(String[] args) {Test test = new Test();Producer producer = test.new Producer();Consumer consumer = test.new Consumer();producer.start();consumer.start();}class Consumer extends Thread{@Overridepublic void run() {consume();}private void consume() {while(true){synchronized (queue) {while(queue.size() == 0){try {System.out.println("队列空,等待数据");queue.wait();} catch (InterruptedException e) {e.printStackTrace();queue.notify();}}queue.poll(); //每次移走队首元素queue.notify();System.out.println("从队列取走一个元素,队列剩余"+queue.size()+"个元素");}}}}class Producer extends Thread{@Overridepublic void run() {produce();}private void produce() {while(true){synchronized (queue) {while(queue.size() == queueSize){try {System.out.println("队列满,等待有空余空间");queue.wait();} catch (InterruptedException e) {e.printStackTrace();queue.notify();}}queue.offer(1); //每次插入一个元素queue.notify();System.out.println("向队列取中插入一个元素,队列剩余空间:"+(queueSize-queue.size()));}}}}}
public class Test {private int queueSize = 10;private ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(queueSize);public static void main(String[] args) {Test test = new Test();Producer producer = test.new Producer();Consumer consumer = test.new Consumer();producer.start();consumer.start();}class Consumer extends Thread{@Overridepublic void run() {consume();}private void consume() {while(true){try {queue.take();System.out.println("从队列取走一个元素,队列剩余"+queue.size()+"个元素");} catch (InterruptedException e) {e.printStackTrace();}}}}class Producer extends Thread{@Overridepublic void run() {produce();}private void produce() {while(true){try {queue.put(1);System.out.println("向队列取中插入一个元素,队列剩余空间:"+(queueSize-queue.size()));} catch (InterruptedException e) {e.printStackTrace();}}}}}
java 多线程阻塞队列 与 阻塞方法与和非阻塞方法的更多相关文章
- 【java多线程】队列系统之说说队列Queue
转载:http://benjaminwhx.com/2018/05/05/%E8%AF%B4%E8%AF%B4%E9%98%9F%E5%88%97Queue/ 1.简介 Queue(队列):一种特殊的 ...
- 使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点?
我感觉很多项目使用java或者c的多线程库+线程安全的queue数据结构基本上可以实现goroutine+channel开发能达到的需求,所以请问一下为什么说golang更适合并发服务端的开发呢?使用 ...
- “全栈2019”Java多线程第二十八章:公平锁与非公平锁详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- 是否可以从一个static方法内部调用非static方法?
不可以.静态成员不能调用非静态成员. 非static方法属于对象,必须创建一个对象后,才可以在通过该对象来调用static方法.而static方法调用时不需要创建对象,通过类就可以调用该方法.也就是说 ...
- python3 封装之property 多态 绑定方法classmethod 与 非绑定方法 staticmethod
property 特性 什么是特性property property 是一种特殊的属性,访问它时会执行一段功能(函数),然后返回值 例如 BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而 ...
- Java多线程:队列与阻塞队列
1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...
- java多线程之队列
1.注:先不看阻塞与否,这ReentrantLock的使用方式就能说明这个类是线程安全类. 2.线程安全的类,BlockingQueue,ConcurrentLinkedQueue.这些都是线程安全的 ...
- 【java多线程】队列系统之LinkedBlockingQueue源码
转载:https://blog.csdn.net/tonywu1992/article/details/83419448 http://benjaminwhx.com/archives/ 1.简介 上 ...
- java并发编程(8)原子变量和非阻塞的同步机制
原子变量和非阻塞的同步机制 一.锁的劣势 1.在多线程下:锁的挂起和恢复等过程存在着很大的开销(及时现代的jvm会判断何时使用挂起,何时自旋等待) 2.volatile:轻量级别的同步机制,但是不能用 ...
随机推荐
- spring boot更换日志为log4j2
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...
- java 调整jvm堆大小上限
针对单个类,eclipse中调整jvm的运行参数,加上这么一句: -Xmx80m 即可把堆上限调整到80m. 关键字: BEA JRockit
- ORACLE经常使用命令
1 怎样查看数据库中都有什么表? select * from sys.user_tables; 2 怎样链接数据库 sqlplus /nolog;conn sys/oracle as sysdba; ...
- maven 亲测可用国内镜像 阿里云(20170123)
来源于:http://www.jianshu.com/p/4d5bb95b56c5 http://blog.csdn.net/qq_27093465/article/details/52982484 ...
- 用setitimer实现多个定时器
从这篇文章中可以看出,setitimer只能实现一个定时器,如果多次调用setitimer,旧值都会被覆盖掉. 如何用setitimer实现多个定时器呢?下面是我的一个实现,具体的方法是: 用链表从小 ...
- Java中的平衡树
leetcode 729 给定一堆线段,每个线段都有一个起点.一个终点,用数组[(beg1,end1),(beg2,end2),(beg3,end3)......]来表示.可以提出以下问题: 这些线段 ...
- SDL的基础知识以及利用SDL播放视频
原文地址:http://blog.csdn.net/i_scream_/article/details/52714378 此博文相关知识点从雷神的博客以及视频学习,截图也是用了他的课件, 雷神博客地址 ...
- python学习笔记——multiprocessing 多进程组件 进程池Pool
1 进程池Pool基本概述 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量时间,如果操作的对象数目不大时,还可以直接适用Process类动态生成 ...
- debian系在线安装软件apt-get命令族
一.背景 apt-get install/remove在线安装/卸载文件真是方便极了. 但是有时候安装/卸载文件不清楚文件在服务器上的实际命名,例如想安装sndfile.应该执行下面哪个命令呢? ap ...
- C#实现相似QQ的隐藏浮动窗口、消息闪动
功能简单介绍 当语音客服系统登录成功进入主界面时,本聊天工具将会自己主动隐藏在左下角位置,当鼠标移动到左下角时,自己主动弹出,当鼠标移开聊天窗口时,自己主动隐藏.假设想让聊天窗口固定在桌面.仅仅要拖动 ...