zoukankan      html  css  js  c++  java
  • 线程高级应用-心得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 }
  • 相关阅读:
    [剑指Offer]判断一棵树为平衡二叉树(递归)
    [HDOJ]Coin Change(DP)
    01背包、完全背包
    [CodeForces_618C]Constellation
    [Codeforces_713A]Sonya and Queries
    C++位运算符
    [codeforces_597B] Restaurant(贪心)
    [LeetCode_98]Validate Binary Search Tree
    [LeetCode_96] Unique Binary Search Trees
    [LeetCode_105]Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/cxxjohnson/p/6261903.html
Copyright © 2011-2022 走看看