您的位置:首页 > 产品设计 > UI/UE

Java中的阻塞队列ArrayBlockingQueue的使用

2014-05-19 22:34 671 查看
ArrayBlockingQueue是Java5中提供的阻塞队列,可以自定义阻塞队列的大小,有多种插入数据和取出数据的方法。每种方法执行时的效果不一样 具体看下图(JDK文档的截图):



/*
* 放入数据(阻塞模式)
* 1、put(e);(阻塞模式:如果队列中的数据容量已达上限,则处于阻塞状态 ,当队列中的容量小于上限值  则立即放入)
* 2、add(e);(非阻塞模式:如果队列中数据容量已达上限,则抛出异常)
* 3、offer(e);(非阻塞模式:如果队列中数据容量已达上限,则返回false)
* 4、offer(e, time, unit) 超时模式 如果单位时间内没有放入数据 则返回false
*/


/*
* 取出数据
* 1、take();(阻塞模式:如果队列中的没有数据,则处于阻塞状态 ,当队列中的一有数据  则立即取出)
* 2、remove();(非阻塞模式:如果队列中的没有数据,则抛出异常)
* 3、poll();(非阻塞模式:如果队列中的没有数据,则返回null)
* 4、poll(time, unit) 超时模式 如果单位时间内没有取出数据 则返回null
*/


ArrayBlockingQueue 应用示例代码:

import java.util.concurrent.ArrayBlockingQueue;

public class ArrayBlockingQueueTest
{
public static void main(String[] args)
{
//定义一个容量为3的阻塞队列
final ArrayBlockingQueue<Integer> queue =
new ArrayBlockingQueue<Integer>(3);

//开启两个线程用于向队列中存储数据
for(int i = 0; i < 2; i++)
{
new Thread(new Runnable()
{
@Override
public void run()
{
while(true)
{
try
{
Thread.sleep((long) (Math.random() * 100));
System.out.println("线程:" + Thread.currentThread().getName()
+ " 准备放数据...");
/* * 放入数据(阻塞模式) * 1、put(e);(阻塞模式:如果队列中的数据容量已达上限,则处于阻塞状态 ,当队列中的容量小于上限值 则立即放入) * 2、add(e);(非阻塞模式:如果队列中数据容量已达上限,则抛出异常) * 3、offer(e);(非阻塞模式:如果队列中数据容量已达上限,则返回false) * 4、offer(e, time, unit) 超时模式 如果单位时间内没有放入数据 则返回false */
queue.put(1);
System.out.println("线程:" + Thread.currentThread().getName()
+ " 已经放入数据。队列中目前有:" + queue.size() + " 条数据。");
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

}).start();
}

//开启一个线程 用于从队列中取数据
new Thread(new Runnable()
{
@Override
public void run()
{
while(true)
{
try
{
Thread.sleep((long) (Math.random() * 1000));
System.out.println("线程:" + Thread.currentThread().getName()
+ " 准备取数据...");
/* * 取出数据 * 1、take();(阻塞模式:如果队列中的没有数据,则处于阻塞状态 ,当队列中的一有数据 则立即取出) * 2、remove();(非阻塞模式:如果队列中的没有数据,则抛出异常) * 3、poll();(非阻塞模式:如果队列中的没有数据,则返回null) * 4、poll(time, unit) 超时模式 如果单位时间内没有取出数据 则返回null */
queue.take();
System.out.println("线程:" + Thread.currentThread().getName()
+ " 已经取出数据。队列中目前有:" + queue.size() + " 条数据。");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

}).start();
}
}


使用ArrayBlockingQueue实现线程间同步通信的功能

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueCommunicationTest
{
static PrintInfo printer = new PrintInfo();
public static void main(String[] args)
{
Thread t1 = new Thread(new Runnable()
{

@Override
public void run()
{
for(int i = 0; i < 20; i++)
{
printer.printSubThread(i);
}
}
});

t1.start();

for (int i = 0; i < 20; i++)
{
printer.printMainThread(i);
}
}
}

class PrintInfo
{
/*
* 使用两个容量为1的阻塞队列 实现线程同步通信的功能
*/
BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);

/**
* 匿名构造方法
* 不管实例化对象时调用的是哪个构造方法 首先都会执行匿名构造方法
*/
{
try
{
//将queue2装满 为的是阻塞主线程
queue2.put(1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

public void printSubThread(int loop)
{
try
{
queue1.put(1);
for(int i = 0; i < 20; i++)
{
System.out.println("Sub Thread Num:" + i + "#loop:" + loop);
}
//取出queue2的值 为了让主线程不再阻塞
queue2.take();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}

public void printMainThread(int loop)
{
try
{
queue2.put(1);
for(int i = 0; i < 50; i++)
{
System.out.println("Main Thread Num:" + i + "#loop:" + loop);
}
//取出queue1的值 为了让子线程不再阻塞
queue1.take();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: