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

1.阻塞队列知识点

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

  1 2. 案例分析
  2 一:
  3 package com.java5.thread.newSkill;
  4 
  5 import java.util.concurrent.ArrayBlockingQueue;
  6 import java.util.concurrent.BlockingQueue;
  7 
  8 public class BlockingQueueTest {
  9 
 10     /**
 11      * 阻塞队列类:BlockingQueue
 12      */
 13     public static void main(String[] args) {
 14         
 15         final BlockingQueue queue = new ArrayBlockingQueue(3);
 16         
 17         for(int i=0;i<2;i++){
 18             new Thread(){
 19                 public void run() {
 20                     while(true){
 21                     try{
 22                         Thread.sleep((long)Math.random()*10000);
 23                         System.out.println(Thread.currentThread().getName()+" 准备放数据!");
 24                         queue.put(1);
 25                         System.out.println(Thread.currentThread().getName()+" 已经放了数据,队列目前有: "+queue.size()+" 个数据!");
 26                     }catch(Exception e){
 27                         e.printStackTrace();
 28                     }
 29                     }
 30                 }
 31             }.start();
 32         }
 33         
 34         new Thread(){
 35             public void run() {
 36                 while(true){
 37                 try{
 38                     //将此处睡眠时间分别改成100和1000,观察运行结果
 39                     /*
 40                      *    休息时间短,理论上应是:数据永远达不到三个,总是在第二个就被取走了;
 41                      *  但是本人操作总是有三个数据出现,不知道的原因所在,
 42                      *  感兴趣的大牛可以复制 代码测试一下;
 43                      *    休息时间长,数据总是三个,但是放的多取的少
 44                      */
 45                     Thread.sleep(100);
 46                     System.out.println(Thread.currentThread().getName()+" 准备取数据!");
 47                     queue.take();
 48                     System.out.println(Thread.currentThread().getName()+" 已经取走数据,队列目前有: "+queue.size()+" 个数据!");
 49                 }catch(Exception e){
 50                     e.printStackTrace();
 51                 }
 52                 }
 53             }
 54         }.start();
 55     }
 56 
 57 }
 58 
 59 二:
 60 package com.java5.thread.newSkill;
 61 
 62 import java.util.concurrent.ArrayBlockingQueue;
 63 import java.util.concurrent.BlockingQueue;
 64 
 65 /**
 66  * 
 67  */
 68 public class BlockingQueueCommunication {
 69 
 70     public static void main(String[] args) {
 71         final Business business = new Business();
 72         new Thread(new Runnable() {
 73 
 74             @Override
 75             public void run() {
 76                 for (int i = 1; i <= 50; i++) {
 77                     business.sub(i);
 78                 }
 79             }
 80         }).start();
 81 
 82         for (int i = 1; i <= 50; i++) {
 83             business.main(i);
 84         }
 85 
 86     }
 87 
 88     /*
 89      * 编写一个有子方法(用来调用子线程)和主方法(调用主线程)的业务类 加static是因为上面new的对象是final的,为了把这个类弄成外部类,
 90      * 但是外部又有同名类,所以这样搞; 产生的类名为:BlockingQueueCommunication.Bussiness
 91      */
 92     static class Business {
 93 
 94         BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
 95         BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
 96 
 97         /*
 98          * 这样直接在大括号内写的代码叫匿名构造方法;匿名构造方法优先与其他任何构造方法执行。
 99          * 带上static关键字的叫做静态代码块,不带的也叫普通代码块
100          * 静态代码块在类加载的时候执行,只会执行一次;普通代码块创建几个对象就会执行几次。
101          */
102 
103         {
104             try {
105                 System.out.println("我执行了,一上来就把queue2中放了一个数据");
106                 queue2.put(1);
107             } catch (InterruptedException e) {
108                 e.printStackTrace();
109             }
110         }
111 
112         //此处要注意的问题:一定不要用同步锁sychronized,否则效果达不到还会出粗
113         //因为阻塞已经类似到了同步的功能,再用同步锁就是死锁了
114         public void sub(int i) {
115             try {
116                 queue1.put(1);
117             } catch (InterruptedException e) {
118                 e.printStackTrace();
119             }
120             for (int j = 1; j <= 10; j++) {
121                 System.out.println("sub thread sequence of  " + j
122                         + " ,loop of  " + i);
123             }
124             try {
125                 queue2.take();
126             } catch (InterruptedException e) {
127                 e.printStackTrace();
128             }
129         }
130 
131         public void main(int i) {
132             try {
133                 queue2.put(1);
134             } catch (InterruptedException e) {
135                 e.printStackTrace();
136             }
137             for (int j = 1; j <= 100; j++) {
138                 System.out.println("main thread sequence of  " + j
139                         + " ,loop of  " + i);
140             }
141             try {
142                 queue1.take();
143             } catch (InterruptedException e) {
144                 e.printStackTrace();
145             }
146         }
147     }
148 }
原文地址:https://www.cnblogs.com/cxxjohnson/p/6261903.html