使用数组简单实现的阻塞队列
2017-08-17 15:13
441 查看
阻塞队列的定义:队列是一种先进先出的数据结构,如果队列为空,从队列中获取元素,消费者线程会阻塞,如果队列已经满了,生产者线程就会阻塞
这里使用lock锁和condition接口实现
代码如下:
package cn.erong.blockqueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用数组实现阻塞队列
* @author zhouy
*
*/
public class ArrayBlockingQueue<T> {
private Lock lock = new ReentrantLock();
private Object[] item = new Object[4];
private int startIndex,endIndex,count;//初始化时,默认值为0,count 定义为队列中元素的数目
private Condition notfull = lock.newCondition();
private Condition notempty = lock.newCondition();
public void add(T t){
lock.lock();
try{
System.out.println("存放值"+t);
while(count==item.length){
try {
System.out.println("队列已满,阻塞put线程");
notfull.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
item[startIndex++] = t;
count++;
if(startIndex==item.length){
startIndex=0;
}
notempty.signal();
}finally{
lock.unlock();
}
}
public T take(){
lock.lock();//获取锁不能写在try块中,如果发生异常,锁会被释放
try{
while(count==0){
try {
System.out.println("队列空了,阻塞take线程");
notempty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t =(T)item[endIndex++];
System.out.println("取值"+t);
count--;
if(endIndex==item.length){
endIndex = 0;
}
notfull.signal();
return t;
}finally{
lock.unlock();
}
}
}
可以简单的测试一下:
package cn.erong.blockqueue;
public class BlockTest {
public static void main(String[] args) {
//启动一个子线程,不断的生产元素
final ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<3;i++){
queue.add(i);
}
}
});
try {
thread.join();
thread.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
//主线程不断的获取,显然最后,主线程会阻塞
for(int i=0;i<15;i++){
queue.take();
}
}
}
结果如下:
队列空了,阻塞take线程
存放值0
存放值1
存放值2
取值0
取值1
取值2
队列空了,阻塞take线程
这里使用lock锁和condition接口实现
代码如下:
package cn.erong.blockqueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用数组实现阻塞队列
* @author zhouy
*
*/
public class ArrayBlockingQueue<T> {
private Lock lock = new ReentrantLock();
private Object[] item = new Object[4];
private int startIndex,endIndex,count;//初始化时,默认值为0,count 定义为队列中元素的数目
private Condition notfull = lock.newCondition();
private Condition notempty = lock.newCondition();
public void add(T t){
lock.lock();
try{
System.out.println("存放值"+t);
while(count==item.length){
try {
System.out.println("队列已满,阻塞put线程");
notfull.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
item[startIndex++] = t;
count++;
if(startIndex==item.length){
startIndex=0;
}
notempty.signal();
}finally{
lock.unlock();
}
}
public T take(){
lock.lock();//获取锁不能写在try块中,如果发生异常,锁会被释放
try{
while(count==0){
try {
System.out.println("队列空了,阻塞take线程");
notempty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t =(T)item[endIndex++];
System.out.println("取值"+t);
count--;
if(endIndex==item.length){
endIndex = 0;
}
notfull.signal();
return t;
}finally{
lock.unlock();
}
}
}
可以简单的测试一下:
package cn.erong.blockqueue;
public class BlockTest {
public static void main(String[] args) {
//启动一个子线程,不断的生产元素
final ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<3;i++){
queue.add(i);
}
}
});
try {
thread.join();
thread.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
//主线程不断的获取,显然最后,主线程会阻塞
for(int i=0;i<15;i++){
queue.take();
}
}
}
结果如下:
队列空了,阻塞take线程
存放值0
存放值1
存放值2
取值0
取值1
取值2
队列空了,阻塞take线程
相关文章推荐
- C语言使用数组实现简单队列
- 使用数组实现的简单队列结构
- 使用数组实现双端队列
- GCD实战一:使用串行队列实现简单的预加载
- 深入GCD(四):使用串行队列实现简单的预加载
- 使用数组实现栈和循环队列(JAVA语言)
- 一个简单的阻塞队列实现
- 使用数组实现简单线性表功能
- c语言用简单数组实现循环队列
- iOS学习笔记10(5)—GCD实战一:使用串行队列实现简单的预加载
- 使用数组实现队列
- 数据结构学习笔记(3)_使用数组实现简单线性表功能
- C_综合使用数组实现简单的学生成绩管理系统
- 使用数组实现一个随机队列
- 基于C++11的阻塞队列简单实现
- GCD实战一:使用串行队列实现简单的预加载
- GCD实战一:使用串行队列实现简单的预加载
- PHP使用数组实现队列
- 数据结构学习笔记(3)_使用数组实现简单线性表功能
- GCD实战一:使用串行队列实现简单的预加载