Condition的功能类似在传统线程技术中的Object.wait()和Object.natify()的功能,传统线程技术实现的互斥只能一个线程单独干,不能说这个线程干完了通知另一个线程来干,Condition就是解决这个问题的,实现线程间的通信。比如CPU让小弟做事,小弟说我先歇着并通知大哥,大哥就开始做事。

Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

Condition实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。

在java5中,一个锁可以有多个条件,每个条件上可以有多个线程等待,通过调用await()方法,可以让线程在该条件下等待。当调用signalAll()方法,又可以唤醒该条件下的等待的线程。

下面以银行存取款案例阐述Condition用法:

假设有一个账户,多个用户(线程)在同时操作这个账户,有的存款有的取款,存款随便存,取款有限制,不能透支,任何试图透支的操作都将等待里面有足够存款才执行操作。

package com.ljq.test.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class ConditionTest {
public static void main(String[] args) {
ConditionTest test = new ConditionTest(); // 创建并发访问的账户
Account myAccount = test.new Account("95599200901215522", 10000);
// 创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
Thread t1 = test.new DrawThread("张三", myAccount, 11000);
Thread t2 = test.new SaveThread("李四", myAccount, 3600);
Thread t3 = test.new DrawThread("王五", myAccount, 2700);
Thread t4 = test.new SaveThread("老张", myAccount, 600);
Thread t5 = test.new DrawThread("老牛", myAccount, 1300);
Thread t6 = test.new SaveThread("胖子", myAccount, 2000); // 执行各个线程
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
pool.execute(t6);
// 关闭线程池
pool.shutdown();
} /**
* 存款线程类
*/
public class SaveThread extends Thread {
private String name; // 操作人
private Account account; // 账户
private int x; // 存款金额 SaveThread(String name, Account account, int x) {
this.name = name;
this.account = account;
this.x = x;
} public void run() {
account.saving(x, name);
}
} /**
* 取款线程类
*/
public class DrawThread extends Thread {
private String name; // 操作人
private Account account; // 账户
private int x; // 存款金额 DrawThread(String name, Account account, int x) {
this.name = name;
this.account = account;
this.x = x;
} public void run() {
account.drawing(x, name);
}
} /**
* 银行账户
*/
public class Account {
private String id; // 账号
private int cash; // 账户余额
private Lock lock = new ReentrantLock(); // 账户锁
private Condition _save = lock.newCondition(); // 存款条件
private Condition _draw = lock.newCondition(); // 取款条件 Account(String id, int cash) {
this.id = id;
this.cash = cash;
} /**
* 存款
*
* @param x 操作金额
* @param name 操作人
*/
public void saving(int x, String name) {
lock.lock(); // 获取锁
if (x > 0) {
cash += x; // 存款
System.out.println(name + "存款" + x + ",当前余额为" + cash);
}
_draw.signalAll(); // 唤醒所有等待的取款线程。
lock.unlock(); // 释放锁
} /**
* 取款
*
* @param x
* 操作金额
* @param name
* 操作人
*/
public void drawing(int x, String name) {
lock.lock(); // 获取锁
try {
if (cash - x < 0) {
System.out.println(name + "取款失败[余额不足],取款" + x + ",当前余额为" + cash);
_draw.await(); // 阻塞取款操作
} else {
cash -= x; // 取款
System.out.println(name + "取款" + x + ",当前余额为" + cash);
}
_save.signalAll(); // 唤醒所有等待的存款操作
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁
}
}
} }

  

java5 Condition用法--实现线程间的通信的更多相关文章

  1. Java-JUC(九):使用Lock替换synchronized,使用Condition的await,singal,singalall替换object的wait,notify,notifyall实现线程间的通信

    Condition: condition接口描述了可能会与锁有关的条件变量.这些用法上与使用object.wait访问隐式监视器类似,但提供了更强大的功能.需要特别指出的是,单个lock可能与多个Co ...

  2. Java:多线程,使用同步锁(Lock)时利用Condition类实现线程间通信

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

  3. QThread与其他线程间相互通信

    转载请注明链接与作者huihui1988 QThread的用法其实比较简单,只需要派生一个QThread的子类,实现其中的run虚函数就大功告成, 用的时候创建该类的实例,调用它的start方法即可. ...

  4. 关于synchronized和lock 的使用及其在线程间的通信

    题目要求:子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次 synchronized的使用 import java.util.conc ...

  5. 【转】Java学习---线程间的通信

    [原文]https://www.toutiao.com/i6572378564534993415/ 两个线程间的通信 这是我们之前的线程. 执行效果:谁抢到资源,谁运行~ 实现线程交替执行: 这里主要 ...

  6. Java多线程之线程的状态以及线程间协作通信导致的线程状态转换

      转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html  一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Ru ...

  7. 【转】Java学习:Java中的线程之线程间的通信

    hello各位小伙伴 今天我们来搞一下 线程之间的通信 ( • ̀ω•́ )✧ 让线程按照我们的想法来执行 两个线程间的通信 这是我们之前的线程. 执行效果:谁抢到资源,谁运行~ 实现线程交替执行: ...

  8. 并发编程系列小结(线程安全,synchronized,脏读,线程间的通信wait/notify,线程的三种实现方式Demo,可替代wait/notify的方法)

    线程安全: 当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法就是线程安全的) synchronized: 可以在任意对象或方法上加锁,而加锁的这段代码称为 ...

  9. iOS开发多线程篇—线程间的通信

    iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...

随机推荐

  1. JavaScript例子

    模态框(JavaScript) <!DOCTYPE html> <html lang="en"> <head> <meta charset ...

  2. html中<video>显示视频的时候,MP4的格式问题

    html支持的视频格式:HTML5视频 注意 浏览器对mp4 的编码方式要求的非常严格 视频编码必须是H.264 音频编码必须是: AAC

  3. [转载]Lwip之IP/MAC地址冲突检测

    from: http://blog.csdn.net/tianjueyiyi/article/details/51097447 LWIP是个轻量级的TCP/IP协议栈,之所以说轻量级,是因为作者将主体 ...

  4. 21天学通C++_Day3_Part1

    今天奔跑吧兄弟来杭电了,决定不去看,宅在科协继续啃(反正去了也看不到咯),继续继续,今天白天没课,希望可以更两个. 0.C风格字符串 在数组中间把某个字符替换成‘\0’并不会改变数组的长度,但是显示时 ...

  5. WPF XMAL获取元素的父元素,子元素

    /// 获得指定元素的父元素 /// </summary> /// <typeparam name="T">指定页面元素</typeparam> ...

  6. 51nod 1995 三子棋

    小的时候大家一定玩过“井”字棋吧.也就是在九宫格中,只要任意行.列,或者任意连续对角线上面出现三个相同的,就能获胜.现在小明和小花也在玩三子棋,但是他们不是在九宫格里,而是在3×4的格子里面.现在小明 ...

  7. LeetCode Next Greater Element III

    原题链接在这里:https://leetcode.com/problems/next-greater-element-iii/description/ 题目: Given a positive 32- ...

  8. yii 操作cookie

    原文地址:http://blog.sina.com.cn/s/blog_664c9f650100yqkn.html 设置cookie: $cookie = new CHttpCookie('mycoo ...

  9. (转)java.lang.RuntimeException: Missing type parameter

    java.lang.RuntimeException: Missing type parameter (2015-04-07 14:35:51)   分类: 技术 程序中用到了gson的new typ ...

  10. 定时任务&&找出两个list的不同

    /*-------------------------application-context.xml------------------------------*/ <?xml version= ...