线程高级应用-心得7-java5线程并发库中阻塞队列Condition的应用及案例分析
1.阻塞队列知识点


阻塞队列重要的有以下几个方法,具体用法可以参考帮助文档;区别说的很清楚,第一个种方法不阻塞直接抛异常;第二种方法是boolean型的,阻塞返回flase;第三种方法直接阻塞。

2. 案例分析一:package com.java5.thread.newSkill;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class BlockingQueueTest {/** * 阻塞队列类:BlockingQueue */public static void main(String[] args) {final BlockingQueue queue = new ArrayBlockingQueue(3);for(int i=0;i<2;i++){new Thread(){public void run() {while(true){try{Thread.sleep((long)Math.random()*10000);System.out.println(Thread.currentThread().getName()+" 准备放数据!");queue.put(1);System.out.println(Thread.currentThread().getName()+" 已经放了数据,队列目前有: "+queue.size()+" 个数据!");}catch(Exception e){e.printStackTrace();}}}}.start();}new Thread(){public void run() {while(true){try{//将此处睡眠时间分别改成100和1000,观察运行结果/* * 休息时间短,理论上应是:数据永远达不到三个,总是在第二个就被取走了; * 但是本人操作总是有三个数据出现,不知道的原因所在, * 感兴趣的大牛可以复制 代码测试一下; * 休息时间长,数据总是三个,但是放的多取的少 */Thread.sleep(100);System.out.println(Thread.currentThread().getName()+" 准备取数据!");queue.take();System.out.println(Thread.currentThread().getName()+" 已经取走数据,队列目前有: "+queue.size()+" 个数据!");}catch(Exception e){e.printStackTrace();}}}}.start();}}二:package com.java5.thread.newSkill;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;/** * */public class BlockingQueueCommunication {public static void main(String[] args) {final Business business = new Business();new Thread(new Runnable() {@Overridepublic void run() {for (int i = 1; i <= 50; i++) {business.sub(i);}}}).start();for (int i = 1; i <= 50; i++) {business.main(i);}}/* * 编写一个有子方法(用来调用子线程)和主方法(调用主线程)的业务类 加static是因为上面new的对象是final的,为了把这个类弄成外部类, * 但是外部又有同名类,所以这样搞; 产生的类名为:BlockingQueueCommunication.Bussiness */static class Business {BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);/* * 这样直接在大括号内写的代码叫匿名构造方法;匿名构造方法优先与其他任何构造方法执行。 * 带上static关键字的叫做静态代码块,不带的也叫普通代码块 * 静态代码块在类加载的时候执行,只会执行一次;普通代码块创建几个对象就会执行几次。 */{try {System.out.println("我执行了,一上来就把queue2中放了一个数据");queue2.put(1);} catch (InterruptedException e) {e.printStackTrace();}}//此处要注意的问题:一定不要用同步锁sychronized,否则效果达不到还会出粗//因为阻塞已经类似到了同步的功能,再用同步锁就是死锁了public void sub(int i) {try {queue1.put(1);} catch (InterruptedException e) {e.printStackTrace();}for (int j = 1; j <= 10; j++) {System.out.println("sub thread sequence of " + j+ " ,loop of " + i);}try {queue2.take();} catch (InterruptedException e) {e.printStackTrace();}}public void main(int i) {try {queue2.put(1);} catch (InterruptedException e) {e.printStackTrace();}for (int j = 1; j <= 100; j++) {System.out.println("main thread sequence of " + j+ " ,loop of " + i);}try {queue1.take();} catch (InterruptedException e) {e.printStackTrace();}}}}