zoukankan      html  css  js  c++  java
  • Lock&Condition实现线程同步通信

    Definition

    Condition的功能类似于传统线程技术中的Object.wait和Object.notify的功能。

    一个锁内部可以有多个Condition,即有多路等待和通知。

    在传统的线程机制中一个监视器对象只能有一路等待和通知,要想实现多路等待和通知,必须嵌套使用多个同步监视器对象。

    Example

    多路等待示例:

    1、模板代码

     class BoundedBuffer {
       final Lock lock = new ReentrantLock();
       final Condition notFull  = lock.newCondition(); 
       final Condition notEmpty = lock.newCondition(); 
    
       final Object[] items = new Object[100];
       int putptr, takeptr, count;
    
       public void put(Object x) throws InterruptedException {
         lock.lock();
         try {
           while (count == items.length)
             notFull.await();
           items[putptr] = x;
           if (++putptr == items.length) putptr = 0;
           ++count;
           notEmpty.signal();
         } finally {
           lock.unlock();
         }
       }
    
       public Object take() throws InterruptedException {
         lock.lock();
         try {
           while (count == 0)
             notEmpty.await();
           Object x = items[takeptr];
           if (++takeptr == items.length) takeptr = 0;
           --count;
           notFull.signal();
           return x;
         } finally {
           lock.unlock();
         }
       }
     }

    2、实例代码

     1 public class ConditionCommunication {
     2 
     3     public static void main(String[] args) {
     4 
     5         final Business business = new Business();
     6         new Thread(
     7                 new Runnable(){
     8                         public void run(){
     9                             for(int i=1;i<=10;i++){
    10                                 business.sub(i);
    11                             }
    12                         }
    13                     }
    14                 ).start();
    15 
    16         for(int i=1;i<=50;i++){
    17             business.main(i);
    18         }
    19     }
    20     
    21     static class Business {
    22         Lock lock = new ReentrantLock();
    23         Condition condition = lock.newCondition();
    24         private boolean bShouldSub = true;
    25         
    26         public void sub(int i){
    27             lock.lock();
    28             try{
    29                 while(!bShouldSub){//while用于防止虚假唤醒
    30                     try {
    31                         condition.await();
    32                     } catch (Exception e) {
    33                         // TODO Auto-generated catch block
    34                         e.printStackTrace();
    35                     }
    36                 }
    37                 for(int j=1;j<=10;j++){
    38                     System.out.println("sub thread sequece of " + j + ",loop of " + i);
    39                 }
    40                 bShouldSub = false;
    41                 condition.signal();
    42             }finally{
    43                 lock.unlock();
    44             }
    45         }
    46         
    47         public void main(int i){
    48             lock.lock();
    49             try{
    50                 while(bShouldSub){
    51                     try {
    52                         condition.await();
    53                     } catch (Exception e) {
    54                         // TODO Auto-generated catch block
    55                         e.printStackTrace();
    56                     }
    57                 }
    58                 for(int j=1;j<=100;j++){
    59                         System.out.println("main thread sequece of " + j + ",loop of " + i);
    60                     }
    61                 bShouldSub = true;
    62                 condition.signal();
    63             }finally{
    64                 lock.unlock();
    65             }
    66         }
    67     }
    68 }

    3、3线程交互示例:

    本例中包含3个线程,main、sub2和sub3,3个线程交替执行先是main然后是sub2,sub2又交给sub3,sub3再交给main,如此循环往复执行50次。

      1 public class ThreeConditionCommunication {
      2 
      3     public static void main(String[] args) {
      4 
      5         final Business business = new Business();
      6         new Thread(
      7                 new Runnable(){
      8                         public void run(){
      9                             for(int i=1;i<=50;i++){
     10                                 business.sub2(i);
     11                             }
     12                         }
     13                     }
     14                 ).start();
     15         
     16         new Thread(
     17                 new Runnable(){
     18                         public void run(){
     19                             for(int i=1;i<=50;i++){
     20                                 business.sub3(i);
     21                             }
     22                         }
     23                     }
     24                 ).start();
     25 
     26         for(int i=1;i<=50;i++){
     27             business.main(i);
     28         }
     29     }
     30     
     31     static class Business {
     32         Lock lock = new ReentrantLock();
     33         //Condition定义
     34         Condition condition1 = lock.newCondition();
     35         Condition condition2 = lock.newCondition();
     36         Condition condition3 = lock.newCondition();
     37         private int ShouldSub = 1;
     38         
     39         public void sub2(int i){
     40             lock.lock();
     41             try{
     42                 //while用于防止虚假唤醒,很重要
     43                 while(ShouldSub != 2){
     44                     try {
     45                         condition2.await();
     46                     } catch (Exception e) {
     47                         // TODO Auto-generated catch block
     48                         e.printStackTrace();
     49                     }
     50                 }
     51                 for(int j=1;j<=10;j++){
     52                     System.out.println("sub2 thread sequece of " + j + ",loop of " + i);
     53                 }
     54                 ShouldSub = 3;
     55                 condition3.signal();
     56             }finally{
     57                 lock.unlock();
     58             }
     59         }
     60         
     61         public void sub3(int i){
     62             lock.lock();
     63             try{
     64                 while(ShouldSub != 3){
     65                     try {
     66                         condition3.await();
     67                     } catch (Exception e) {
     68                         // TODO Auto-generated catch block
     69                         e.printStackTrace();
     70                     }
     71                 }
     72                 for(int j=1;j<=20;j++){
     73                     System.out.println("sub3 thread sequece of " + j + ",loop of " + i);
     74                 }
     75                 ShouldSub = 1;
     76                 condition1.signal();
     77             }finally{
     78                 lock.unlock();
     79             }
     80         }
     81         
     82         public void main(int i){
     83             lock.lock();
     84             try{
     85                 while(ShouldSub != 1){
     86                     try {
     87                         condition1.await();
     88                     } catch (Exception e) {
     89                         // TODO Auto-generated catch block
     90                         e.printStackTrace();
     91                     }
     92                 }
     93                 for(int j=1;j<=100;j++){
     94                     System.out.println("main thread sequece of " + j + ",loop of " + i);
     95                 }
     96                 ShouldSub = 2;
     97                 condition2.signal();
     98             }finally{
     99                 lock.unlock();
    100             }
    101         }
    102     }
    103 }

    部分运行结果:

    main thread sequece of 94,loop of 34
    main thread sequece of 95,loop of 34
    main thread sequece of 96,loop of 34
    main thread sequece of 97,loop of 34
    main thread sequece of 98,loop of 34
    main thread sequece of 99,loop of 34
    main thread sequece of 100,loop of 34
    sub2 thread sequece of 1,loop of 34
    sub2 thread sequece of 2,loop of 34
    sub2 thread sequece of 3,loop of 34
    sub2 thread sequece of 4,loop of 34
    sub2 thread sequece of 5,loop of 34
    sub2 thread sequece of 6,loop of 34
    sub2 thread sequece of 7,loop of 34
    sub2 thread sequece of 8,loop of 34
    sub2 thread sequece of 9,loop of 34
    sub2 thread sequece of 10,loop of 34
    sub3 thread sequece of 1,loop of 34
    sub3 thread sequece of 2,loop of 34
    sub3 thread sequece of 3,loop of 34
  • 相关阅读:
    PHP底层工作原理
    php WebSocket 简单实现demo
    php部署调优
    php简单随机实现发红包程序
    在Android中调用USB摄像头
    在addroutes后,$router.options.routes没有更新的问题(手摸手,带你用vue撸后台 读后感)
    Vue+elementUI开发中 Cannot read property 'resetFields' of undefined 问题解决以及原因分析
    如何在debug vue-cli建立的项目
    在Node.js使用Promise的方式操作Mysql(续)
    express框架中如何只执行一次res响应操作
  • 原文地址:https://www.cnblogs.com/shen-smile/p/5145645.html
Copyright © 2011-2022 走看看