Java线程-线程池-条件变量
条件变量是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线程-线程池-条件变量相关推荐
- Linux线程同步之条件变量
与互斥锁不同,条件变量是用来等待而不是用来上锁的.条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.通常条件变量和互斥锁同时使用. 条件变量使我们可以睡眠等待某种条件出现.条件变量是利用线程间共享 ...
- [转]Linux线程同步之条件变量
与互斥锁不同,条件变量是用来等待而不是用来上锁的.条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.通常条件变量和互斥锁同时使用. 条件变量使我们可以睡眠等待某种条件出现.条件变量是利用线程间共享 ...
- 线程同步之条件变量:pthread_cond_signal和pthread_cond_wait
在多线程编程下,常常出现A线程要等待B线程条件完成后再继续进行,这里等待方式有两种: 1.使用锁+轮询 使用这种方法可以很简单的实现,但是会有一定的性能消耗,其还有一个点要好好把握,就是一次轮询没有结 ...
- Linux——线程同步(条件变量、POSIX信号量)和线程池
一.线程同步 (一).概念 线程同步是一种多线程关系,指的是线程之间按照特定顺序访问临界资源,进而能够避免线程饥饿问题. 所谓线程饥饿指的是某个线程长期"霸占"临界资源,导致其他线 ...
- 【C++ 语言】线程安全队列 ( 条件变量 | 线程调度 )
文章目录 I . 线程简单使用 II . 互斥锁 III . 条件变量 线程同步 IV . 完整代码示例 006_ThreadSafeQueue.h 006_ThreadSafeQueue.cpp S ...
- linux线程同步(2)-条件变量
一.概述 上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...
- Linux 线程学习之条件变量
互斥锁:用来上锁. 条件变量:用来等待,当条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.通常条件变量和互斥锁同时使用. 函数介绍: 1. 名称: pthread_cond_init 目标: 条 ...
- 3线程同步:条件变量
1条件变量 条件变量给多个线程提供了一个汇合的场所. 依赖的头文件 #include<pthread.h> 函数声明 定义分配条件变量 pthread_cond_t cond =PTHRE ...
- linux 条件变量函数,Linux线程同步之条件变量
条件变量变量也是出自POSIX线程标准,另一种线程同步机制,.主要用来等待某个条件的发生.可以用来同步同一进程中的各个线程.当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量 ...
最新文章
- CodeChefSeries Sum (伯努利数+生成函数+FFT)
- python——logging模块
- 跳转控制语句之break
- 第一章 计算机网络 3 标准化工作和相关组织 [计算机网络笔记] -简单浏览了解即可
- java ThreadLocal理解和使用
- 树莓派python开发教程_树莓派教程(基于python编程)--入门篇
- SpringBoot常用注解以及作用
- Linux主机SSH免密码登录设置
- 大气辐射示意简单图_地理笔记 | N21 自然地理——大气的组成与垂直分层
- 使用Object、param标签在页面显示PDF文件
- VB 串口编程 开发心得
- python导出pdf文件怎么只有一页_python利用PyPDF2拆分pdf文件成单页
- 服务器打开显示选择键盘布局,更改服务器上的TTY键盘布局?
- Nginx之13运筹帷幄 - (VeryNginx)
- 2021-04-19一万小时定律
- 摄像机模型和双目建模三维点云的理解
- 微信公众平台-小程序开发工具源码
- 日式风格小荷才露尖尖角
- Apple:万亿收入指日可待
- sql语句里面最难的not exists,exists,口语化解释(个人笔记)
热门文章
- yahoo军规的思考
- 二阶系统欠阻尼状态极点位置对阶跃响应的影响
- 肚脐眼周围疼痛怎么回事,10种方法来预防
- 把上面的苹果咬掉一口,再打印
- java 微信自定义菜单 java微信接口开发 公众平台 SSM redis shiro 多数据源
- 刘一男词汇课(从ancestor到universa):书上有路勤为径,学海无涯“懂“作舟
- 如何用PPT绘制设计一个分割型环形图?
- Java 设计模式之责任链模式实现的三种方式
- JProfiler使用(Java分析工具)
- 计算机云教室管理制度,《中云中学专用教室管理制度》一.doc