Java--concurrent并发包下阻塞队列介绍
JDK提供了7中阻塞队列,这里介绍其中3中,剩余的以此类推原理相同。
1.ArrayBlockingQueue
package com.seeyon.queue; import java.util.concurrent.ArrayBlockingQueue; /**
* Created by yangyu on 16/11/27.
*/ /**
* ArrayBlockingQueue是数组结构组成的有界阻塞队列
* 当队列已经满了的时候,put操作会阻塞当前线程,直到队列发生出队操作然后会唤醒put线程在入队
* 当队列为空的时候,take操作会阻塞当前线程,直到队列发生入队操作后会唤醒take线程进行出队
*/
public class TestArrayBlockingQueue {
public static void main(String[] args) {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue(1); try {
queue.put("1111");
/**
* 该操作会被阻塞,知道队列发生出队操作
*/
queue.put("2222");
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
2.LinkedBlockingQueue:链表实现的有界阻塞队列
3.PriorityBlockingQueue:支持优先级的无界阻塞队列
4.DelayQueue
package com.seeyon.queue; import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit; import static java.util.concurrent.TimeUnit.NANOSECONDS; /**
* Created by yangyu on 16/11/27.
*/ /**
* DelayQueue是一个支持延时获取元素的无界队列
* DelayQueue可以用于如下场景:
* 1.缓存系统的的设计:用DelayQueue保存缓存元素的有效期,用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取到元素,说明该元素过期了
* 2.定时任务调度:使用DelayQueue保存当天会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,TimerQueue就是使用DelayQueue实现的
* DelayQueue的原理:
* 1.当线程put元素的时候,DelayQueue会对你put的元素通过其本身的compareTo方法进行排序,延时时间越短的顺序越靠近队列头部
* 2.当线程take元素的时候,DelayQueue会检测当前是否有Thread已经在等待队头元素了,如果有的话,那么只能阻塞当前前程,等已经取到队头
* 的Thread完成以后再唤醒。
* 如果没有Thread在等待队头元素的话,那么会查询一下队头元素还剩多少Delay时间,并且将当前线程设置为队头等待线程,然后让当前线程wait剩余
* Delay时间后在来获取队头元素。
*/
public class TestDelayQueue {
public static void main(String[] args) {
DelayQueue<Message> delayQueue = new DelayQueue<>();
delayQueue.put(new Message(2000,"yangyu")); try {
System.out.println(delayQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("end");
} private static class Message implements Delayed{ private long nanoTime; private String data; Message(long millisTime ,String data){
this.nanoTime = now()+millisTime*(1000*1000);
this.data = data;
} private final long now(){
return System.nanoTime();
} @Override
public long getDelay(TimeUnit unit) {
return unit.convert(nanoTime - now(), NANOSECONDS);
} @Override
public int compareTo(Delayed other) {
if (other == this) // compare zero if same object
return 0;
if (other instanceof Message) {
Message x = (Message) other;
long diff = nanoTime - x.nanoTime;
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
else
return 1;
}
long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
}
}
5.SynchronousQueue
import java.util.concurrent.SynchronousQueue; /**
* Created by yangyu on 16/11/27.
*/ /**
* SynchronousQueue是一个不存储数据的队列,只是做数据的的传递工作
* 同步队列,一个put操作必须等待一个take操作,否则线程被阻塞
* 同样,一个take操作必须等待一个put操作,否则线程被阻塞
*
* Executors中newCachedThreadPool()(可缓存线程池),就是使用的SynchronousQueue
* 当一个任务被放入可缓存线程池以后,会调用SynchronousQueue的offer方法来判断是否有正在等待取任务的线程
* offer方法:如果有线程正在等待取任务则将任务交给该线程并且返回true,如果没有线程等待取任务则返回false
* 如果没有正在等待的线程,那么可缓存线程池会重新启动一个线程来执行这个任务
* 当该线程执行完任务以后,会去SynchronousQueue队列中获取数据,等待60s,直到60s还未获取到任务则就自行关闭了
*/
public class TestSynchronousQueue {
public static void main(String[] args) {
SynchronousQueue<String> strings = new SynchronousQueue<>();
Thread t =new Thread(()->{
try {
/**
* 该take操作会被阻塞,直到后面的strings.put("yangyu")操作后,当前线程才会被唤醒
*/
System.out.println(strings.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start(); try {
Thread.sleep(2000);
/**
* 唤醒阻塞线程并且传递数据
*/
strings.put("yangyu");
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("完成"); }
}
6.LinkedTransferQueue
7.LinkedBlockingDeqeue:是一个链表结构组成的双向阻塞队列,可以从队列的两端插入或者移出元素。
Java--concurrent并发包下阻塞队列介绍的更多相关文章
- Java中常用的七个阻塞队列介绍第一篇
Java中常用的七个阻塞队列介绍第一篇 在上一篇我们对Java中的队列分类做了简单的介绍.本文咱们主要来聊聊阻塞队列中的七个常用子类.这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个 ...
- Java中常用七个阻塞队列的总结
Java队列总结 通过前面文章的学习,我们对Java中常用队列做了介绍.本文,咱们来对队列做个总结吧. 首先,我们介绍了现实生活中的实际场景(排队买票等),来告诉我们为什么需要使用队列. 队列是一种先 ...
- 9.并发包非阻塞队列ConcurrentLinkedQueue
jdk1.7.0_79 队列是一种非常常用的数据结构,一进一出,先进先出. 在Java并发包中提供了两种类型的队列,非阻塞队列与阻塞队列,当然它们都是线程安全的,无需担心在多线程并发环境所带来的不可 ...
- 最全java多线程总结3——了解阻塞队列和线程安全集合不
看了前两篇你肯定已经理解了 java 并发编程的低层构建.然而,在实际编程中,应该经可能的远离低层结构,毕竟太底层的东西用起来是比较容易出错的,特别是并发编程,既难以调试,也难以发现问题,我们还是 ...
- JAVA多线程提高十二:阻塞队列应用
一.类相关属性 接口BlockingQueue<E>定义: public interface BlockingQueue<E> extends Queue<E> { ...
- JAVA多线程学习十五 - 阻塞队列应用
一.类相关属性 接口BlockingQueue<E>定义: public interface BlockingQueue<E> extends Queue<E> { ...
- java多线程(8)---阻塞队列
阻塞队列 再写阻塞列队之前,我写了一篇有关queue集合相关博客,也主要是为这篇做铺垫的. 网址:[java提高]---queue集合 在这篇博客中我们接触的队列都是非阻塞队列,比如Priority ...
- java线程(7)——阻塞队列BlockingQueue
回顾: 阻塞队列,英文名叫BlockingQueue.首先他是一种队列,联系之前Java基础--集合中介绍的Queue与Collection,我们就很容易开始今天的阻塞队列的学习了.来看一下他们的接口 ...
- 25、Java并发性和多线程-阻塞队列
以下内容转自http://ifeve.com/blocking-queues/: 阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操 ...
随机推荐
- fir.im Weekly - 一切从知识重构开始
一年之计在于春,大自然开始了新元素的重构.你的知识库是否也该重构更新呢? 本期 fir.im Weekly 包含最新的Android.iOS 开发工具.源码和好玩的UI 动画分享,希望对你有用. Sw ...
- KnockoutJS 3.X API 第四章 表单绑定(9) value绑定
目的 value绑定主要用于DOM元素给视图模型赋值用的.通常用于<input><select><textarea>等元素. value绑定与text绑定的区别在于 ...
- LigerUI学习使用
LigerUI有如下主要特点: 使用简单,轻量级 控件实用性强,功能覆盖面大,可以解决大部分企业信息应用的设计场景 快速开发,使用LigerUI可以比传统开发减少极大的代码量 易扩展,包括默认参数.表 ...
- CSS3选择器的研究
属性选择器 [title]:选择带有title属性的元素 [title='hello']:选择属性是title并且值是hello的元素 [title~='hello']:选择属性是title并且部分值 ...
- 咱们来聊聊JS中的异步,以及如何异步,菜鸟版
为什么需要异步?why?来看一段代码. 问题1: for(var i=0;i<100000;i++){ } alert('hello world!!!'); 这段代码的意思是执行100...次后 ...
- Web前端优化最佳实践及工具集锦
Web前端优化最佳实践及工具集锦 发表于2013-09-23 19:47| 21315次阅读| 来源Googe & Yahoo| 118 条评论| 作者王果 编译 Web优化Google雅虎P ...
- java多线程的等待唤醒机制及如何解决同步过程中的安全问题
/* class Person{ String name; String sex; boolean flag = true; public void setPerson(String name, St ...
- 牛顿法与拟牛顿法学习笔记(三)DFP 算法
机器学习算法中经常碰到非线性优化问题,如 Sparse Filtering 算法,其主要工作在于求解一个非线性极小化问题.在具体实现中,大多调用的是成熟的软件包做支撑,其中最常用的一个算法是 L-BF ...
- 《HelloGitHub月刊》第03期
<HelloGithub>第03期 兴趣是最好的老师,而<HelloGitHub> 就是帮你找到兴趣! 因为我比较熟悉python语言,所以月刊中python语言的项目居多,个 ...
- Android中include标签的使用
在Android的开发中,我们知道布局文件可以让我们很方便的对各个UI控件进行位置安排跟属性设置,而在程序中可以直接取得控件并赋予对应操作功能.但是,如果是一个复杂的界面设计,我们把所有布局都放在一个 ...