条件变量是Java5线程当中很重要的一个概念,顾名思义,条件变量就是条件当中的一种变量,这里的条件没有实际意义,仅仅是个标记而已。
条件变量都实现了java.util.concurrent.locks.Condition接口,条件对象的实例化是通过一个lock对象上调用newCondition()方法来获取的,这样条件就和一个锁对象绑定起来,Java当中的条件变量只能和锁配合使用,来控制并发程序访问竞争资源的安全。
条件变量的出现是为了更精细的控制线程的等待和唤醒,Java5之前,线程的等待与唤醒靠的是Object对象的wait()、notify和notifyAll()方法,这样的处理不够精细。
在Java5当中,一个锁可以有多个条件,每个条件上可以有多个线程等待,通过调用await()方法,可以使线程在该条件下进行等待。当调用了signalAll(),又可以唤醒该条件下等待的线程。
条件变量比较抽象,它不是自然语言当中的条件概念,它是控制程序的一种有效手段。
代码如下:

public class Main {public static void main(String args[]){//创建并发访问的账户MyCount myCount=new MyCount("370911199212233321",10000);//创建一个线程池ExecutorService executorService= Executors.newFixedThreadPool(2);//创建六个线程Thread thread1=new SaveMoneyThread("张三",myCount,1000);Thread thread2=new DrawMoneyThread("王五",myCount,5000);Thread thread3=new SaveMoneyThread("赵六",myCount,2000);Thread thread4=new SaveMoneyThread("李四",myCount,1000);Thread thread5=new DrawMoneyThread("吴京",myCount,8000);Thread thread6=new SaveMoneyThread("狗子",myCount,7000);Thread thread7=new DrawMoneyThread("王二麻子",myCount,9000);//执行各个线程executorService.execute(thread1);executorService.execute(thread2);executorService.execute(thread3);executorService.execute(thread4);executorService.execute(thread5);executorService.execute(thread6);executorService.execute(thread7);//关闭线程池executorService.shutdown();}}class MyCount {private String oid;                                 //账号private int cash;                                   //账户余额private Lock lock=new ReentrantLock();              //锁private Condition saveCondition=lock.newCondition();//存款条件private Condition drawCondition=lock.newCondition();//取款条件MyCount(String oid,int cash){this.oid=oid;this.cash=cash;}/***  存款* @param x 存款金额* @param name 存款人*/public void saveMoney(int x,String name){lock.lock();if(x>0){this.cash+=x;//存款System.out.println(name+"存款"+x+","+"当前余额为"+this.cash);}//唤醒取款的等待线程this.drawCondition.signalAll();//释放锁lock.unlock();}/*** 取款* @param x 取款金额* @param name 取款人*/public void drawMoney(int x,String name){try {lock.lock();if(x-this.cash>0){drawCondition.await();}else {this.cash-=x;System.out.println(name+"取款"+x+",当前余额为"+this.cash);}//唤醒所有的存款条件saveCondition.signalAll();} catch (InterruptedException e) {e.printStackTrace();}finally {//释放锁lock.unlock();}}
}class DrawMoneyThread extends Thread {private String name;    //操作人private MyCount myCount;//账户private int x;          //取款金额DrawMoneyThread(String name,MyCount myCount,int x){this.name=name;this.myCount=myCount;this.x=x;}/*** 取款*/@Overridepublic void run() {this.myCount.drawMoney(this.x,this.name);}
}class SaveMoneyThread extends Thread {private String name;    //操作人private MyCount myCount;//账户private int x;          //存款金额SaveMoneyThread(String name,MyCount myCount,int x){this.name=name;this.myCount=myCount;this.x=x;}/*** 存款*/@Overridepublic void run() {this.myCount.saveMoney(this.x,this.name);}
}

如果不用Condition来实现,用synchronized来实现,代码如下:

public class Main {public static void main(String args[]){//创建并发访问的账户MyCount myCount=new MyCount("370911199212233321",10000);//创建一个线程池ExecutorService executorService= Executors.newFixedThreadPool(2);//创建六个线程Thread thread1=new SaveMoneyThread("张三",myCount,1000);Thread thread2=new DrawMoneyThread("王五",myCount,5000);Thread thread3=new SaveMoneyThread("赵六",myCount,2000);Thread thread4=new SaveMoneyThread("李四",myCount,1000);Thread thread5=new DrawMoneyThread("吴京",myCount,8000);Thread thread6=new SaveMoneyThread("狗子",myCount,7000);Thread thread7=new DrawMoneyThread("王二麻子",myCount,9000);//执行各个线程executorService.execute(thread1);executorService.execute(thread2);executorService.execute(thread3);executorService.execute(thread4);executorService.execute(thread5);executorService.execute(thread6);executorService.execute(thread7);//关闭线程池executorService.shutdown();}}class MyCount {private String oid;                                 //账号private int cash;                                   //账户余额MyCount(String oid,int cash){this.oid=oid;this.cash=cash;}/***  存款* @param x 存款金额* @param name 存款人*/public synchronized void saveMoney(int x,String name){if(x>0){this.cash+=x;//存款System.out.println(name+"存款"+x+","+"当前余额为"+this.cash);}//唤醒取款的等待线程notifyAll();}/*** 取款* @param x 取款金额* @param name 取款人*/public synchronized void drawMoney(int x,String name){try {if(x-this.cash>0){wait();}else {this.cash-=x;System.out.println(name+"取款"+x+",当前余额为"+this.cash);}} catch (InterruptedException e) {e.printStackTrace();}notifyAll();}
}class DrawMoneyThread extends Thread {private String name;    //操作人private MyCount myCount;//账户private int x;          //取款金额DrawMoneyThread(String name,MyCount myCount,int x){this.name=name;this.myCount=myCount;this.x=x;}/*** 取款*/@Overridepublic void run() {this.myCount.drawMoney(this.x,this.name);}
}class SaveMoneyThread extends Thread {private String name;    //操作人private MyCount myCount;//账户private int x;          //存款金额SaveMoneyThread(String name,MyCount myCount,int x){this.name=name;this.myCount=myCount;this.x=x;}/*** 存款*/@Overridepublic void run() {this.myCount.saveMoney(this.x,this.name);}
}

用同步代码块来实现:

public class Main {public static void main(String args[]){//创建并发访问的账户MyCount myCount=new MyCount("370911199212233321",10000);//创建一个线程池ExecutorService executorService= Executors.newFixedThreadPool(2);//创建六个线程Thread thread1=new SaveMoneyThread("张三",myCount,1000);Thread thread2=new DrawMoneyThread("王五",myCount,5000);Thread thread3=new SaveMoneyThread("赵六",myCount,2000);Thread thread4=new SaveMoneyThread("李四",myCount,1000);Thread thread5=new DrawMoneyThread("吴京",myCount,8000);Thread thread6=new SaveMoneyThread("狗子",myCount,7000);Thread thread7=new DrawMoneyThread("王二麻子",myCount,9000);//执行各个线程executorService.execute(thread1);executorService.execute(thread2);executorService.execute(thread3);executorService.execute(thread4);executorService.execute(thread5);executorService.execute(thread6);executorService.execute(thread7);//关闭线程池executorService.shutdown();}}class MyCount {private String oid;                                 //账号private int cash;                                   //账户余额MyCount(String oid,int cash){this.oid=oid;this.cash=cash;}/***  存款* @param x 存款金额* @param name 存款人*/public void saveMoney(int x,String name){if(x>0){synchronized (this){this.cash+=x;//存款System.out.println(name+"存款"+x+","+"当前余额为"+this.cash);//唤醒取款的等待线程notifyAll();}}}/*** 取款* @param x 取款金额* @param name 取款人*/public void drawMoney(int x,String name){synchronized (this){try {if(x-this.cash>0){wait();}else {this.cash-=x;System.out.println(name+"取款"+x+",当前余额为"+this.cash);}} catch (InterruptedException e) {e.printStackTrace();}notifyAll();}}
}class DrawMoneyThread extends Thread {private String name;    //操作人private MyCount myCount;//账户private int x;          //取款金额DrawMoneyThread(String name,MyCount myCount,int x){this.name=name;this.myCount=myCount;this.x=x;}/*** 取款*/@Overridepublic void run() {this.myCount.drawMoney(this.x,this.name);}
}class SaveMoneyThread extends Thread {private String name;    //操作人private MyCount myCount;//账户private int x;          //存款金额SaveMoneyThread(String name,MyCount myCount,int x){this.name=name;this.myCount=myCount;this.x=x;}/*** 存款*/@Overridepublic void run() {this.myCount.saveMoney(this.x,this.name);}
}

Java线程-线程池-条件变量相关推荐

  1. Linux线程同步之条件变量

    与互斥锁不同,条件变量是用来等待而不是用来上锁的.条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.通常条件变量和互斥锁同时使用. 条件变量使我们可以睡眠等待某种条件出现.条件变量是利用线程间共享 ...

  2. [转]Linux线程同步之条件变量

    与互斥锁不同,条件变量是用来等待而不是用来上锁的.条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.通常条件变量和互斥锁同时使用. 条件变量使我们可以睡眠等待某种条件出现.条件变量是利用线程间共享 ...

  3. 线程同步之条件变量:pthread_cond_signal和pthread_cond_wait

    在多线程编程下,常常出现A线程要等待B线程条件完成后再继续进行,这里等待方式有两种: 1.使用锁+轮询 使用这种方法可以很简单的实现,但是会有一定的性能消耗,其还有一个点要好好把握,就是一次轮询没有结 ...

  4. Linux——线程同步(条件变量、POSIX信号量)和线程池

    一.线程同步 (一).概念 线程同步是一种多线程关系,指的是线程之间按照特定顺序访问临界资源,进而能够避免线程饥饿问题. 所谓线程饥饿指的是某个线程长期"霸占"临界资源,导致其他线 ...

  5. 【C++ 语言】线程安全队列 ( 条件变量 | 线程调度 )

    文章目录 I . 线程简单使用 II . 互斥锁 III . 条件变量 线程同步 IV . 完整代码示例 006_ThreadSafeQueue.h 006_ThreadSafeQueue.cpp S ...

  6. linux线程同步(2)-条件变量

    一.概述                                                    上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...

  7. Linux 线程学习之条件变量

    互斥锁:用来上锁. 条件变量:用来等待,当条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.通常条件变量和互斥锁同时使用. 函数介绍: 1. 名称: pthread_cond_init 目标: 条 ...

  8. 3线程同步:条件变量

    1条件变量 条件变量给多个线程提供了一个汇合的场所. 依赖的头文件 #include<pthread.h> 函数声明 定义分配条件变量 pthread_cond_t cond =PTHRE ...

  9. linux 条件变量函数,Linux线程同步之条件变量

    条件变量变量也是出自POSIX线程标准,另一种线程同步机制,.主要用来等待某个条件的发生.可以用来同步同一进程中的各个线程.当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量 ...

最新文章

  1. CodeChefSeries Sum (伯努利数+生成函数+FFT)
  2. python——logging模块
  3. 跳转控制语句之break
  4. 第一章 计算机网络 3 标准化工作和相关组织 [计算机网络笔记] -简单浏览了解即可
  5. java ThreadLocal理解和使用
  6. 树莓派python开发教程_树莓派教程(基于python编程)--入门篇
  7. SpringBoot常用注解以及作用
  8. Linux主机SSH免密码登录设置
  9. 大气辐射示意简单图_地理笔记 | N21 自然地理——大气的组成与垂直分层
  10. 使用Object、param标签在页面显示PDF文件
  11. VB 串口编程 开发心得
  12. python导出pdf文件怎么只有一页_python利用PyPDF2拆分pdf文件成单页
  13. 服务器打开显示选择键盘布局,更改服务器上的TTY键盘布局?
  14. Nginx之13运筹帷幄 - (VeryNginx)
  15. 2021-04-19一万小时定律
  16. 摄像机模型和双目建模三维点云的理解
  17. 微信公众平台-小程序开发工具源码
  18. 日式风格小荷才露尖尖角
  19. Apple:万亿收入指日可待
  20. sql语句里面最难的not exists,exists,口语化解释(个人笔记)

热门文章

  1. yahoo军规的思考
  2. 二阶系统欠阻尼状态极点位置对阶跃响应的影响
  3. 肚脐眼周围疼痛怎么回事,10种方法来预防
  4. 把上面的苹果咬掉一口,再打印
  5. java 微信自定义菜单 java微信接口开发 公众平台 SSM redis shiro 多数据源
  6. 刘一男词汇课(从ancestor到universa):书上有路勤为径,学海无涯“懂“作舟
  7. 如何用PPT绘制设计一个分割型环形图?
  8. Java 设计模式之责任链模式实现的三种方式
  9. JProfiler使用(Java分析工具)
  10. 计算机云教室管理制度,《中云中学专用教室管理制度》一.doc