您的位置:首页 > 其它

使用Condition控制线程通信:

2016-09-21 14:03 417 查看
使用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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: