阻塞队列

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

看下面的例子:

    import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue; public class BlockingQueueTest{
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> bqueue = new ArrayBlockingQueue<String>(20);
for (int i = 0; i < 30; i++) {
//将指定元素添加到此队列中
bqueue.put("加入元素" + i);
System.out.println("向阻塞队列中添加了元素:" + i);
}
System.out.println("程序到此运行结束,即将退出----");
}
}

输出结果如下:

从执行结果中可以看出,由于队列中元素的数量限制在了20个,因此添加20个元素后,其他元素便在队列外阻塞等待,程序并没有终止。

如果队列已满后,我们将队首元素移出,并可以继续向阻塞队列中添加元素,修改代码如下:

    import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue; public class BlockingQueueTest{
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> bqueue = new ArrayBlockingQueue<String>(20);
for (int i = 0; i < 30; i++) {
//将指定元素添加到此队列中
bqueue.put("" + i);
System.out.println("向阻塞队列中添加了元素:" + i);
if(i > 18){
//从队列中获取队头元素,并将其移出队列
System.out.println("从阻塞队列中移除元素:" + bqueue.take());
}
}
System.out.println("程序到此运行结束,即将退出----");
}
}

执行结果如下:

从结果中可以看出,当添加了第20个元素后,我们从队首移出一个元素,这样便可以继续向队列中添加元素,之后每添加一个元素,便从将队首元素移除,这样程序便可以执行结束。

阻塞栈

阻塞栈与阻塞队列相似,只是它是Java 6中加入的新特性,阻塞栈的接口java.util.concurrent.BlockingDeque也有很多实现类,使用方法也比较相似,具体查看JDK文档。

下面同样给出一个简单的例子:

    import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque; public class BlockingDequeTest {
public static void main(String[] args) throws InterruptedException {
BlockingDeque<String> bDeque = new LinkedBlockingDeque<String>(20);
for (int i = 0; i < 30; i++) {
//将指定元素添加到此阻塞栈中
bDeque.putFirst("" + i);
System.out.println("向阻塞栈中添加了元素:" + i);
}
System.out.println("程序到此运行结束,即将退出----");
}
}

执行结果如下:

程序依然会阻塞等待,我们改为如下代码:

    import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque; public class BlockingDequeTest {
public static void main(String[] args) throws InterruptedException {
BlockingDeque<String> bDeque = new LinkedBlockingDeque<String>(20);
for (int i = 0; i < 30; i++) {
//将指定元素添加到此阻塞栈中
bDeque.putFirst("" + i);
System.out.println("向阻塞栈中添加了元素:" + i);
if(i > 18){
//从阻塞栈中取出栈顶元素,并将其移出
System.out.println("从阻塞栈中移出了元素:" + bDeque.pollFirst());
}
}
System.out.println("程序到此运行结束,即将退出----");
}
}

执行结果如下:

    从结果中可以看出,当添加了第20个元素后,我们从将栈顶元素移处,这样便可以继续向栈中添加元素,之后每添加一个元素,便将栈顶元素移出,这样程序便可以执行结束。

java并发编程(十八)阻塞队列和阻塞栈的更多相关文章

  1. Java并发(十八):阻塞队列BlockingQueue

    阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用. 阻塞队列常用于生产 ...

  2. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  3. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

  4. Java并发编程(八)同步容器

    为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch) 一.为什么会出现同步容器? ...

  5. Java并发编程 (十) 多线程并发拓展

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.死锁 1.死锁的定义 所谓的死锁是指两个或两个以上的线程在等待执行的过程中,因为竞争资源而造成的一种 ...

  6. Java并发编程(八)线程间协作(上)

    多线程并发执行时,不同的线程执行的内容之间可能存在一些依赖关系,比如线程一执行a()方法和c()方法,线程二执行b()方法,方法a()必须在方法b()之前执行,而方法c()必须在方法b()之后执行.这 ...

  7. Java并发编程3-抽象同步队列AQS详解

    AQS是AtractQueuedSynchronizer(队列同步器)的简写,是用来构建锁或其他同步组件的基础框架.主要通过一个int类型的state来表示同步状态,内部有一个FIFO的同步队列来实现 ...

  8. java并发编程(八)多线程环境下安全使用集合

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17200509     在集合API中,最初设计的Vector和Hashtable是多线程安 ...

  9. Java并发编程(八)-- 死锁

    简介 当两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,就称为死锁.在多任务操作系统中,操作系统为了协调不同进程,能否获取系统资源时,为了让系统运作,必须要解决这 ...

  10. Java并发编程(八):线程调度——线程池

    new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { / ...

随机推荐

  1. spring framework核心框架体系结构

    很实用,稀里糊涂的我算是看清了. 很多人都在用spring开发java项目,但是配置maven依赖的时候并不能明确要配置哪些spring的jar,经常是胡乱添加一堆,编译或运行报错就继续配置jar依赖 ...

  2. cocoapods真机调试出现问题解决

    swift中使用cocoapods时,Podfile中必须写上 use_frameworks! 使用cocoapods导入框架在真机调试出现问题的解决方案: 1.build phases 2.+ ne ...

  3. STM32F412应用开发笔记之五:结合W5500实现以太网通讯

    因实际使用需求我们测试一下网络通讯,在NUCLEO-F412ZG测试板上没有以太网部分,我们选择外接一个W5500的实验板.W5500支持SPI接口通讯,DC3.3V供源.而NUCLEO-F412ZG ...

  4. html+css上传文件控件美化

    html上传美化: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. WPF 画心2.0版之元旦快乐

    2017年元旦已经到了,想做一个祝福语的窗口,就把上一篇画心的程序改了改,变成了如下界面. 说下改动的地方,首先窗口没有标题栏了. MainWindow.xaml AllowsTransparency ...

  6. C++ 系列:深拷贝与浅拷贝

    Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...

  7. Js 日期转换函数(UTC时间转换及日期想加减)

    IOS上Js日期转换中new Date("yyyy-mm-dd")不能正常工作,必须使用new Date("yyyy/MM/dd"); 日期相加减: Date. ...

  8. pdf2htmlEx安装及测试

    pdf2htmEx转换效果优秀,可以将pdf转换为html文件,转换速度很快 有两种输出形式, 1.一个pdf对应一个html文件,转换出来的html文件较大 2.一个pdf对应多个html页面,且可 ...

  9. Linux 线程管理

    解析1 LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数.但这个函数的执行过程比较难于理解. pthread_cond_wait()的工 ...

  10. 【原创】内核ShellCode注入的一种方法

    标 题: [原创]内核ShellCode注入的一种方法 作 者: organic 时 间: 2013-05-04,04:34:08 链 接: http://bbs.pediy.com/showthre ...