使用Condition控制线程通信:

使用Condition控制线程通信:
(1)如果不使用synchronized关键字保证同步,而是直接使用Lock对象来保证同步,则系统中不存在隐式的同步监视器,也就不能使用wait() notify() notifyAll()来进行线程通信了
(2)当使用lock对象来保证同步时,Java提供了一个Condition类来保持协调,使用Condition可以让那些已经得到lock对象却无法继续执行的线程释放lock对象,Condition对象也可以唤醒其他处于等待状态的进程。
(3)Condition实例被绑定在一个Lock对象上。要获得Lock实例的Condition实例,调用Lock对象的newCondition()方法即可。Condition类提供了如下三个方法:
awit():类似于隐式同步监视器上的wait()方法,导致当前线程等待,直到其他线程调用该Condition的signal()方法或者signalAll()方法来唤醒该线程
signal():唤醒在此lock对象上等待的单个线程。如果所有线程都在该lock对象上等待,则会选择唤醒其中一个线程,选择是任意性的。
signalAll() 唤醒在此Lock对象上等待的所有线程。

//下面程序中Account使用Lock对象来控制同步,并使用Condition对象来控制线程的协调运行。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {

     //******改变的*******//
     //显式定义Lock对象
     private  final  Lock  lock  =new  ReentrantLock();
     //获得Lock对象对应的Condition
     private  final  Condition  cond  =lock.newCondition();
     //封装账户编号、账户余额的两个成员变量
     private  String  accountNo;
     private   double  balance;
     //标识账户中是否有存款的旗标
     private  boolean  flag=false;

     public  Account(){

     }

     //构造器
     public Account(String   accountNo,double  balance){
           this.accountNo=accountNo;
           this.balance=balance;
     }

     public String getAccountNo() {
           return this.accountNo;
     }
     public void setAccountNo(String accountNo) {
           this.accountNo = accountNo;
     }
//账户余额不允许随便修改,所以只为balance提供getter方法
     public double getBalance() {
           return this.balance;
     }

     public  synchronized  void  draw(double    drawAmount){
           //******改变******
           //加锁
           lock.lock();
           //如果flag为假,表明账户中还没有钱存入进去,取钱方法阻塞
           try {
           if(!  flag){

                     cond.await();
           }
                     else{
                           //执行取钱操作
                          System.out.println(Thread.currentThread().getName()+"取钱:"+drawAmount);
                         balance=balance-drawAmount;
                         System.out.println("余额为:"+balance);
                         //将标识账户已有存款旗标设为false
                         flag= false;
                         //唤醒其他线程
                        cond.signalAll();
                     }

                } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                }
           //使用finally来释放锁
           finally{
                lock.unlock();
           }

           }


     public  synchronized  void  deposit(double  depositAmount){
           lock.lock();
           //如果flag为真,表明账户有钱,存钱方法阻塞
           try{
                if(flag)
                {
                     cond.await();
                }
                //执行存款操作
                else{
                     System.out.println(Thread.currentThread().getName()+"存款"+depositAmount);
                     balance=balance+depositAmount;
                     System.out.println("账户余额为:"+balance);
                     //将标识账户已有存款的旗标设为true
                     flag=true;
                     //唤醒其他线程
                     cond.signalAll();
                }
           }catch(InterruptedException  e){
                e.printStackTrace();

           }

           finally{
                lock.unlock();
           }

     }
     @Override
     public int hashCode() {
           final int prime = 31;
           int result = 1;
           result = prime * result + ((accountNo == null) ? 0 : accountNo.hashCode());
           long temp;
           temp = Double.doubleToLongBits(balance);
           result = prime * result + (int) (temp ^ (temp >>> 32));
           return result;
     }
     @Override
     public boolean equals(Object obj) {
           if (this == obj)
                return true;
           if (obj == null)
                return false;
           if (getClass() != obj.getClass())
                return false;
           Account other = (Account) obj;
           if (accountNo == null) {
                if (other.accountNo != null)
                     return false;
           } else if (!accountNo.equals(other.accountNo))
                return false;
           if (Double.doubleToLongBits(balance) != Double.doubleToLongBits(other.balance))
                return false;
           return true;
     }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值