标签:阻塞队列 blockingqueue arrayblockingqueue 多线程 并发
ArrayBlockingQueue是个有数组支持的有界的阻塞队列。该队列按照先进先出FIFO的原理对元素排序,插入新元素市场队列的尾部,获取新元素是操作队列的开始处。一旦见了建立了缓存区,就不能再增加其容量,试图从已满的队列中方式元素会导致操作阻塞;试图从空的队列中提取元素将导致阻塞。
提拱了四种方法,只有put(),take()才会发生阻塞。
下面是阻塞队列的例子。
package andy.thread.test; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * @author Zhang,Tianyou * @version 2014年11月9日 下午5:29:28 */ public class BlockingQueueTest { public static void main(String[] args) { final int CAPACITY = 3; BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(CAPACITY); for (int i = 0; i < 2; i++) { new Thread() { public void run() { while (true) { try { Thread.sleep((long) (Math.random() * 1000)); System.out.println(Thread.currentThread().getName() + "准备放数据!"); queue.put(1); System.out.println(Thread.currentThread().getName() + "已经放了数据," + "队列目前有" + queue.size() + "个数据"); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } new Thread() { public void run() { while (true) { try { // 将此处的睡眠时间分别改为100和1000,观察运行结果 Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + "准备取数据!"); queue.take(); System.out.println(Thread.currentThread().getName() + "已经取走数据," + "队列目前有" + queue.size() + "个数据"); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } }
Thread-0准备放数据!
Thread-0已经放了数据,队列目前有1个数据
Thread-1准备放数据!
Thread-1已经放了数据,队列目前有2个数据
Thread-0准备放数据!
Thread-0已经放了数据,队列目前有3个数据
Thread-1准备放数据!
Thread-0准备放数据!
Thread-2准备取数据!
Thread-2已经取走数据,队列目前有2个数据
Thread-1已经放了数据,队列目前有3个数据
2、 可以使用阻塞队列完成两个线程循环交替打印。
我们需要定义两个大小唯一的阻塞队列,当一个线程执行时,给另一个队列里存一个值,让另一个线程处于阻塞状态;当前线程执行完毕时,将另一个阻塞队列取出值,让对应的线程执行。
实例如下:
package andy.thread.test; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * @author Zhang,Tianyou * @version 2014年11月9日 下午5:43:28 */ public class BlockingQueueCommunication { public static void main(String[] args) { A a = new A(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 3; i++) { a.sub(i); } } }).start(); for (int i = 1; i <= 3; i++) { a.main(i); } } static class A { BlockingQueue<Integer> mainQueue = new ArrayBlockingQueue<Integer>(1); BlockingQueue<Integer> subQueue = new ArrayBlockingQueue<Integer>(1); // 定义一个匿名构造函数 匿名构造函数在所有的构造函数前开始执行 new多少个实例执行多少次 // static 是在JVM加载时执行 执行一次 { try { subQueue.put(1);// 阻塞子线程 先让第主线程执行 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void sub(int i) { try { // 阻塞主线程 subQueue.put(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("sub thread task is " + i); try { mainQueue.take(); // 子线程执行完 让改主线程执行 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void main(int i) { try { // 阻塞主线程 mainQueue.put(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("main thread task is " + i); try { subQueue.take(); // 子线程执行完 让改主线程执行 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
main thread task is 1
sub thread task is 1
main thread task is 2
sub thread task is 2
main thread task is 3
sub thread task is 3
多线程之阻塞队列ArrayBlockingQueue,BlockingQueue
标签:阻塞队列 blockingqueue arrayblockingqueue 多线程 并发
原文地址:http://blog.csdn.net/fengshizty/article/details/40951265