zoukankan      html  css  js  c++  java
  • lock+Condition

    关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象。Condition类是JDK5中出现的技术,使用它有更好的灵活性,比如可以实现多路通知功能,选择性的进行线程通知,在调度线程上更加灵活。

    使用wait+notify/notifyAll方法进行通知时,被通知的线程却是由JVM随机选择的。但使用reentrantLock结合Condition类是可以实现选择性通知。

    Object类中的wait()方法,相当于Condition类中的await()方法;Object类中的notify()方法,相当于Condition类中的signal()方法。Object类中的notifyAll方法,相当于Condition类中的signalAll()方法。

     打印 12A34B.......5152Z

     1 import java.util.concurrent.locks.Condition;
     2 import java.util.concurrent.locks.Lock;
     3 import java.util.concurrent.locks.ReentrantLock;
     4 
     5 public class Print12A_RC {
     6     
     7     private Lock lock =new ReentrantLock();
     8     private Condition con=lock.newCondition();
     9     private boolean isInt=true;
    10     private int i=1;
    11     private char ch ='A';
    12     public void printInt()
    13     {
    14         try {
    15             lock.lock();
    16             while(!isInt)
    17             {
    18                 con.await();
    19             }
    20             System.out.print((i++)+""+(i++));
    21             isInt=false;
    22             con.signal();
    23         } catch (Exception e) {
    24         }
    25         finally
    26         {
    27             lock.unlock();
    28         }
    29     }
    30     
    31     public void printChar()
    32     {
    33         try {
    34             lock.lock();
    35             while(isInt)
    36             {
    37                 con.await();
    38             }
    39             System.out.print((char)ch);
    40             ch++;
    41             isInt=true;
    42             con.signal();
    43             
    44             
    45         } catch (Exception e) {
    46         }
    47         finally {
    48             lock.unlock();
    49         }
    50     }
    51     
    52     public static void main(String[] args) {
    53         Print12A_RC rc=new Print12A_RC();
    54         Thread aThread=new Thread(new Runnable() {
    55             
    56             @Override
    57             public void run() {
    58                 for(int i=0;i<26;i++)
    59                 {
    60                     rc.printInt();
    61                 }
    62             }
    63         });
    64         Thread bThread =new Thread(new Runnable() {
    65             
    66             @Override
    67             public void run() {
    68                 for(int i=0;i<26;i++)
    69                 {
    70                     rc.printChar();
    71                 }
    72             }
    73         });
    74         aThread.start();
    75         bThread.start();
    76     }
    77 }

     顺序打印,如123123123....

      1 package multiMethod.reentrantLockCondition;
      2 
      3 import java.util.concurrent.locks.Condition;
      4 import java.util.concurrent.locks.ReentrantLock;
      5 
      6 public class PrintByOrder {
      7     ReentrantLock lock =new ReentrantLock();
      8     Condition condition=lock.newCondition();
      9     int printnext=1;
     10     
     11     public void print1()
     12     {
     13         lock.lock();
     14         try{
     15             while(printnext!=1)
     16             {
     17                 condition.await();
     18             }
     19             Thread.sleep(500);//不加此行会不打印,不知什么原因。
     20             System.out.print(1);
     21             printnext=2;
     22             condition.signalAll();
     23         }
     24         catch (Exception e) {
     25             // TODO: handle exception
     26         }
     27         finally{
     28             lock.unlock();
     29         }
     30     }
     31     
     32     public void print2()
     33     {
     34         lock.lock();
     35         try{
     36             while(printnext!=2)
     37             {
     38                 condition.await();
     39             }
     40             System.out.print(2);
     41             printnext=3;
     42             condition.signalAll();
     43         }
     44         catch (Exception e) {
     45         }
     46         finally{
     47             lock.unlock();
     48         }
     49     }
     50     
     51     public void print3()
     52     {
     53         lock.lock();
     54         try{
     55             while(printnext!=3)
     56             {
     57                 condition.await();
     58             }
     59             System.out.print(3);
     60             printnext=1;
     61             condition.signalAll();
     62         }
     63         catch (Exception e) {
     64             // TODO: handle exception
     65         }
     66         finally{
     67             lock.unlock();
     68         }
     69     }
     70 
     71     public static void main(String[] args) {
     72         PrintByOrder order=new PrintByOrder();
     73         Runnable runnable1=new Runnable() {
     74             
     75             @Override
     76             public void run() {
     77                 while(true){
     78                     order.print1();
     79                 }
     80             }
     81         };
     82         
     83         Runnable runnable2=new Runnable() {
     84             
     85             @Override
     86             public void run() {
     87                 while(true){
     88                     order.print2();
     89                 }
     90             }
     91         };
     92         
     93         Runnable runnable3=new Runnable() {
     94             
     95             @Override
     96             public void run() {
     97                 while(true){
     98                     order.print3();
     99                 }
    100             }
    101         };
    102         
    103         new Thread(runnable1).start();
    104         new Thread(runnable2).start();
    105         new Thread(runnable3).start();
    106     }
    107 }

    读写锁,比上面的lock+condition提高效率。

    ReentrantReadWriteLock会使用两把锁来解决问题,一个读锁,一个写锁
    线程进入读锁的前提条件:
        没有其他线程的写锁,
        没有写请求或者有写请求,但调用线程和持有锁的线程是同一个

    线程进入写锁的前提条件:
        没有其他线程的读锁
        没有其他线程的写锁

    简单来说,就是读读共享,写写互斥,读写互斥。

    另外,ReentrantReadWriteLock.readLock 无需newCondition,而ReentrantReadWriteLock.writeLock可以newCondition,用于多个读线程之间的通信。

     1 import java.util.concurrent.locks.ReentrantReadWriteLock;
     2 
     3 public class ReadWriteLock {
     4     private ReentrantReadWriteLock rw= new ReentrantReadWriteLock();
     5     
     6     public void readLock(){
     7         
     8         
     9         try {
    10             rw.readLock().lock();
    11             System.out.println("read before sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
    12             Thread.sleep(2000);
    13             System.out.println("read after sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
    14         } catch (Exception e) {
    15             // TODO: handle exception
    16         }finally{
    17             rw.readLock().unlock();
    18         }
    19     }
    20     
    21     public void writeLock(){
    22         
    23         
    24         try {
    25             rw.writeLock().lock();
    26             System.out.println("write before sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
    27             Thread.sleep(2000);
    28             System.out.println("write after sleep:"+Thread.currentThread().getName()+":"+System.currentTimeMillis());
    29         } catch (Exception e) {
    30             // TODO: handle exception
    31         }finally{
    32             rw.writeLock().unlock();
    33         }
    34     }
    35     
    36     public static void main(String[] args) {
    37         ReadWriteLock rwl=new ReadWriteLock();
    38         Runnable runnable=new Runnable() {
    39             
    40             @Override
    41             public void run() {
    42                 rwl.writeLock();
    43                 rwl.readLock();
    44 
    45             }
    46         };
    47         Thread[] threads=new Thread[10];
    48         for(int i=0;i<5;i++)
    49         {
    50             threads[i]=new Thread(runnable);
    51         }
    52         for(int i=0;i<5;i++)
    53         {
    54             threads[i].start();
    55         }
    56     }
    57 
    58 }
  • 相关阅读:
    Python代写使用矩阵分解法找到类似的音乐
    (转)语义分析透镜洞察婚庆微博用户行为数据
    (转)虎扑论坛基因探秘:社群用户行为数据洞察
    bzoj 4922: [Lydsy1706月赛]Karp-de-Chant Number 贪心+dp
    bzoj 1110: [POI2007]砝码Odw 贪心
    bzoj 3721: PA2014 Final Bazarek 贪心
    bzoj 2563: 阿狸和桃子的游戏 贪心
    bzoj 3999: [TJOI2015]旅游 LCT
    bzoj 4240: 有趣的家庭菜园 树状数组+贪心
    CF369E Valera and Queries kdtree
  • 原文地址:https://www.cnblogs.com/wfq9330/p/8708290.html
Copyright © 2011-2022 走看看