• java中使用Condition控制线程通信(java疯狂讲义)


    如果程序不使用synchronized关键字来保证同步时,而是直接使用Lock对象来保证同步,则系统中不存在隐式的同步监视器,也就不能使用wait()、notify()、notifyAll()方法进行通信了。

    当使用Lock对象来保证同步时,java提供了一个Condition类来保持协调,使用Condition可以让哪些已经得到的Lock对象却无法继续执行的线程释放Lock对象,Condition对象也可以唤醒其他处于等待的线程。

    Condition将同步监视器方法(wait()、notify()、和notifyAll())分解成截然不同的对象,以便通过将这些对象与Lock对象组合使用,为每个对象提供多个等待集(wait-set)。在这种情况下,Lock替代了同步方法或同步代码块,Condition替代了同步监视器的功能。

    Condition实例被绑定在一个Lock对象上,要获得特定的Lock实例的Condition实例,调用Lock对象的newCondition()方法即可。Condition类提供了如下3个方法。

    1、await():类似于隐式同步监视器上的wait()方法,导致当前线程等待,知道其他线程调用该Condition 的signal()方法或signalAll()方法来唤醒该线程,该await()方法有更多的变体,如long awaitNanos(long nanosTimeout)、void awaitUninterruptibly()、awaitUntil(Data deadline)等,可以完成丰富的等待操作。

    2、signal():唤醒在此Lock对象上等待的单个线程,如果所有线程都在该Lock对象上等待,则会选择唤醒其中一个线程,选择是任意性的,只有当前线程放弃对Lock对象的锁定后(使用await()方法),才可以执行被唤醒的线程。

    3、signalAll():唤醒在此Lock对象上等待的所有线程,只有当前线程放弃对该对象Lock对象的锁定后,才可以执行被唤醒的线程。

     1 import java.util.concurrent.locks.Condition;
     2 import java.util.concurrent.locks.ReentrantLock;
     3 public class ConditionClass{
     4     public static void main(String[] args){
     5         Account a=new Account("1",100000);
     6         ThreadClass t=new ThreadClass(a,1000,"NO1");
     7         new Thread(new RunnableClass(a,500)).start();
     8         new Thread(new RunnableClass(a,500)).start();
     9         new Thread(new RunnableClass(a,500)).start();
    10     }
    11 }
    12 class Account{
    13     //显示定义的Lock对象
    14     private final ReentrantLock lock=new ReentrantLock();
    15     //获得指定Lock对象对应的Condition
    16     private final Condition cond=lock.newCondition();
    17     private String name;
    18     private double money;
    19     private boolean flag=false;
    20     public Account(String name,double money){
    21         this.name=name;
    22         this.money=money;
    23     }
    24     public double getMoney(){
    25         return money;
    26     }
    27     public void make(double dymoney){
    28         lock.lock();
    29         try{
    30             if(!flag){      
    31                 System.out.println(Thread.currentThread().getName()+"存储了:"+dymoney);
    32                 money+=dymoney;
    33                 System.out.println("现在余额为:"+money);
    34                 flag=true;
    35                 cond.signalAll();
    36             }else{
    37                 cond.await();
    38             }
    39         }catch(Exception e){System.out.println(e);}finally{
    40             lock.unlock();
    41         }
    42     }
    43     public void take(double dymoney){
    44         lock.lock();
    45         try{
    46             if(flag){
    47                 System.out.println(Thread.currentThread().getName()+"取走了:"+dymoney);
    48                 money-=dymoney;
    49                 flag=false;
    50                 System.out.println("现在余额为:"+money);
    51                 cond.signalAll();
    52             }else{
    53                 cond.await();
    54             }
    55         }catch(Exception e){
    56             System.out.println(e);
    57         }finally{
    58             lock.unlock();
    59         }
    60     }
    61 }
    62 class ThreadClass extends Thread{
    63     private Account account;
    64     private double dymoney;
    65     private String name;
    66     public ThreadClass(Account account,double dymoney,String name){
    67         super(name);
    68         this.account=account;
    69         this.dymoney=dymoney;
    70         start();
    71     }
    72     public void run(){
    73         for(int i=0;i<100;i++){
    74         account.make(dymoney);
    75         }
    76     }
    77     
    78 }
    79 class RunnableClass implements Runnable{
    80     private Account account;
    81     private double dymoney;
    82     public RunnableClass(Account account,double dymoney){
    83         this.account=account;
    84         this.dymoney=dymoney;
    85     }
    86     public void run(){
    87         for(int k=0;k<100;k++){
    88         try{
    89         Thread.sleep(1000);
    90         account.take(dymoney);
    91         }catch(Exception e){}
    92         }
    93     }
    94 }


    显示地使用Lock对象来充当同步监视器,则需要使用Condition对象来暂停、唤醒 指定的线程。

  • 相关阅读:
    sublime text 前端插件安装
    echarts常用的配置项
    2018年okr
    charlse配置
    运维笔记
    移动端开发兼容问题全记录
    centos6下python开发环境搭建
    centos安装python2.7
    centos6安装MariaDB
    pzea上centos6安装mysql57
  • 原文地址:https://www.cnblogs.com/teng-IT/p/4453152.html
Copyright © 2020-2023  润新知