千家信息网

Java怎么使用Condition控制线程通信

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章给大家分享的是有关Java怎么使用Condition控制线程通信的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体如下:一 点睛当使用Lock对象来保证同步时,Ja
千家信息网最后更新 2026年11月03日Java怎么使用Condition控制线程通信

这篇文章给大家分享的是有关Java怎么使用Condition控制线程通信的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

具体如下:

一 点睛

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

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

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

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

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

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

二 代码

1 Account类

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; } // accountNo的setter和getter方法 public void setAccountNo(String accountNo) { this.accountNo = accountNo; } public String getAccountNo() { return this.accountNo; } // 因此账户余额不允许随便修改,所以只为balance提供getter方法, public double getBalance() { return this.balance; } public void draw(double drawAmount) { // 加锁 lock.lock(); try { // 如果flag为假,表明账户中还没有人存钱进去,取钱方法阻塞 if (!flag) { cond.await(); } else { // 执行取钱 System.out.println(Thread.currentThread().getName() + " 取钱:" + drawAmount); balance -= drawAmount; System.out.println("账户余额为:" + balance); // 将标识账户是否已有存款的旗标设为false。 flag = false; // 唤醒其他线程 cond.signalAll(); } } catch (InterruptedException ex) { ex.printStackTrace(); } // 使用finally块来释放锁 finally { lock.unlock(); } } public void deposit(double depositAmount) { lock.lock(); try { // 如果flag为真,表明账户中已有人存钱进去,则存钱方法阻塞 if (flag) // ① { cond.await(); } else { // 执行存款 System.out.println(Thread.currentThread().getName() + " 存款:" + depositAmount); balance += depositAmount; System.out.println("账户余额为:" + balance); // 将表示账户是否已有存款的旗标设为true flag = true; // 唤醒其他线程 cond.signalAll(); } } catch (InterruptedException ex) { ex.printStackTrace(); } // 使用finally块来释放锁 finally { lock.unlock(); } } // 下面两个方法根据accountNo来重写hashCode()和equals()方法 public int hashCode() { return accountNo.hashCode(); } public boolean equals(Object obj) { if(this == obj) return true; if (obj !=null && obj.getClass() == Account.class) { Account target = (Account)obj; return target.getAccountNo().equals(accountNo); } return false; }}

2 DrawThread线程类

public class DrawThread extends Thread{ // 模拟用户账户 private Account account; // 当前取钱线程所希望取的钱数 private double drawAmount; public DrawThread(String name , Account account , double drawAmount) { super(name); this.account = account; this.drawAmount = drawAmount; } // 重复100次执行取钱操作 public void run() { for (int i = 0 ; i < 100 ; i++ ) { account.draw(drawAmount); } }}

3 DepositThread线程类

public class DepositThread extends Thread{ // 模拟用户账户 private Account account; // 当前取钱线程所希望存款的钱数 private double depositAmount; public DepositThread(String name , Account account , double depositAmount) { super(name); this.account = account; this.depositAmount = depositAmount; } // 重复100次执行存款操作 public void run() { for (int i = 0 ; i < 100 ; i++ ) { account.deposit(depositAmount); } }}

4 测试类

public class DrawTest{ public static void main(String[] args) { // 创建一个账户 Account acct = new Account("1234567" , 0); new DrawThread("取钱者" , acct , 800).start(); new DepositThread("存款者甲" , acct , 800).start(); new DepositThread("存款者乙" , acct , 800).start(); new DepositThread("存款者丙" , acct , 800).start(); }}

三 运行结果

......存款者丙 存款:800.0账户余额为:800.0取钱者 取钱:800.0账户余额为:0.0存款者甲 存款:800.0账户余额为:800.0取钱者 取钱:800.0账户余额为:0.0存款者丙 存款:800.0账户余额为:800.0取钱者 取钱:800.0账户余额为:0.0存款者甲 存款:800.0账户余额为:800.0取钱者 取钱:800.0账户余额为:0.0存款者丙 存款:800.0账户余额为:800.0取钱者 取钱:800.0账户余额为:0.0存款者甲 存款:800.0账户余额为:800.0

感谢各位的阅读!关于"Java怎么使用Condition控制线程通信"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

账户 存款 线程 取钱 对象 余额 方法 存款者 同步 实例 旗标 更多 监视 控制 通信 两个 代码 内容 只有 标识 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州紫鲸互联网科技有限公司 科技互联网龙头 金融科技 互联网金融 中国互联网科技发展 狮子座互联网科技有限公司 致聘互联网科技 广州凡科互联网科技 互联网科技公司需要的职位 哈尔滨新华互联网科技学院 互联网科技寓意 阿里互联网科技公司 洛阳昕诺飞互联网科技有限公司 呼和浩特新华互联网科技学院 华夏恒生互联网科技013171 乌鲁木齐新华智原互联网科技学校 产业互联网科技服务公司 厦门江牛科技互联网 普陀区互联网教育科技管理办法 版纳互联网科技选哪家 广西泛欧互联网科技有限公司 美国互联网科技巨头监管 广州互联网科技公司 苏州互联网科技贷款公司 互联网 科技馆 互联网科技项目计划书材料类 互联网科技公司有风险吗 恒生互联网科技业指数调整周期 工业互联网科技成果转化 云鲸互联网络科技有限公司 互联网科技职业技能培训学校
0