java并发编程(十八)阻塞队列和阻塞栈
阻塞队列
阻塞队列是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并发编程(十八)阻塞队列和阻塞栈的更多相关文章
- Java并发(十八):阻塞队列BlockingQueue
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用. 阻塞队列常用于生产 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- Java并发编程实战.笔记十一(非阻塞同步机制)
关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...
- Java并发编程(八)同步容器
为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch) 一.为什么会出现同步容器? ...
- Java并发编程 (十) 多线程并发拓展
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.死锁 1.死锁的定义 所谓的死锁是指两个或两个以上的线程在等待执行的过程中,因为竞争资源而造成的一种 ...
- Java并发编程(八)线程间协作(上)
多线程并发执行时,不同的线程执行的内容之间可能存在一些依赖关系,比如线程一执行a()方法和c()方法,线程二执行b()方法,方法a()必须在方法b()之前执行,而方法c()必须在方法b()之后执行.这 ...
- Java并发编程3-抽象同步队列AQS详解
AQS是AtractQueuedSynchronizer(队列同步器)的简写,是用来构建锁或其他同步组件的基础框架.主要通过一个int类型的state来表示同步状态,内部有一个FIFO的同步队列来实现 ...
- java并发编程(八)多线程环境下安全使用集合
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17200509 在集合API中,最初设计的Vector和Hashtable是多线程安 ...
- Java并发编程(八)-- 死锁
简介 当两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,就称为死锁.在多任务操作系统中,操作系统为了协调不同进程,能否获取系统资源时,为了让系统运作,必须要解决这 ...
- Java并发编程(八):线程调度——线程池
new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { / ...
随机推荐
- 第一天--html
<!Doctype html><html> <head> <meta charset="UTF-8"> ...
- mysql workbench连接不上远程数据库,xshell无法连接远程主机的问题
1.先说xshell无法连接的问题 最近使用virtualbox装了个ubuntu-16.04,然后在win7上使用xshell连接,首先确认win7能ping通虚拟机ip.然后确认是否安装了open ...
- gl.h报错
以下内容摘自:http://blog.csdn.net/kaphen/article/details/24721999 头文件只有#include <gl\gl.h> //OpenGL H ...
- windows下常查看端口占用方法总结
启动Tomcat时又出现端口占用错误.现在把对端口的处理命令和方法进行汇总. 1.查看所有连接的PID 开始--运行--cmd ,输入netstat -ano 找到端口号对应的PID后,从任务管理器 ...
- MongoDB的分片(9)
什么是分片 分片是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载.基本思想就是将集合切成小块,这些块分散到若干片里, ...
- 2 Unique Binary Search Trees II_Leetcode
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...
- Visual Studio (VS IDE) 你必须知道的功能和技巧 - 【.Net必知系列】
前言 本文主要阐述一些Visual Studio开发下需要知道的少部分且比较实用的功能,也是很多人忽略的部分.一些不常用而且冷门的功能不在本文范围,当然本文的尾巴[.Net必知系列]纯属意淫,如有雷同 ...
- 我的微信小程序入门踩坑之旅
前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...
- AVAssetReader+AVAssetReaderTrackOutput播放视频
该文章引用自:http://www.jianshu.com/p/3d5ccbde0de1 IOS 微信聊天发送小视频的秘密(AVAssetReader+AVAssetReaderTrackOutput ...
- js中的 || 与 && 运算符 的使用
&&和||总是傻傻分不清,在这里详细记录一下吧.也给你们分享一下. 表达式a && 表达式b : 计算表达式(或者函数)a的运算结果, 如果为 True, 执行表达式 ...