多线程总结五:线程通信(一)
当线程在程序中运行时,线程的调度具有一定的透明性,程序通常无法准确控制线程的轮换执行,Java提供了一些机制来保证线程协调运行。
1、传统的线程通信借助Object类提供的wait()、notify()和notifyAll()三个方法,这三个方法必须由同步监视器对象来调用。
a、wait():导致当前线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来唤醒该线程;
b、notify():唤醒在此同步监视器上等待的单个线程;
c、notifyAll():唤醒在此同步监视器上等待的所有线程;
2、模拟情景:系统中有两个线程,分别代表存款者和取款者。系统要求存款者和取款者不断重复存款和取款的动作,而且要求每当存款者将钱存入指定账户后,取款者就立即取出该笔钱。不允许存款者连续两次存钱,也不允许取钱者连续两次取钱。
1 /** 2 * @Title: Account3.java 3 * @Package 4 * @author 任伟 5 * @date 2014-12-8 下午6:50:34 6 * @version V1.0 7 */ 8 9 /** 10 * @ClassName: Account3 11 * @Description: 线程安全Account类,提供存钱和取钱的操作 12 * @author 任伟 13 * @date 2014-12-8 下午6:50:34 14 */ 15 public class Account3 { 16 private String accountNo; // 账户编号 17 private double balance; // 账户余额 18 private boolean flag = false; // 表示账户中是否已有存款的骑标 19 20 public String getAccountNo() { 21 return accountNo; 22 } 23 24 public void setAccountNo(String accountNo) { 25 this.accountNo = accountNo; 26 } 27 28 public double getBalance() { 29 return balance; 30 } 31 32 public Account3() { 33 super(); 34 } 35 36 public Account3(String accountNo, double balance) { 37 super(); 38 this.accountNo = accountNo; 39 this.balance = balance; 40 } 41 42 public boolean equals(Object anObject) { 43 if (this == anObject) 44 return true; 45 if (anObject != null && anObject.getClass() == Account.class) { 46 Account target = (Account) anObject; 47 return target.getAccountNo().equals(accountNo); 48 } 49 return false; 50 } 51 52 public int hashCode() { 53 return accountNo.hashCode(); 54 } 55 56 // 取钱操作 57 public synchronized void draw(double drawAmount) { 58 try { 59 if (!flag) {//如果flag为假,表明账户中还没有人存钱进去,取钱方法阻塞 60 wait(); 61 } else {//否则就进行取钱操作 62 if (balance >= drawAmount) { 63 System.out.println(Thread.currentThread().getName() 64 + "取钱成功,吐出钞票:" + drawAmount); 65 try { 66 Thread.sleep(1); 67 } catch (InterruptedException e) { 68 e.printStackTrace(); 69 } 70 balance -= drawAmount; 71 System.out.println("余额为:" + balance); 72 } else { 73 System.out.println(Thread.currentThread().getName() 74 + "取钱失败!余额不足!"); 75 } 76 //将账户是否已有存款的旗标设为false 77 flag = false; 78 //唤醒其他进程 79 notifyAll(); 80 } 81 } catch (Exception e) { 82 e.printStackTrace(); 83 } 84 } 85 86 //存钱操作 87 public synchronized void deposit(double depositAmount){ 88 try{ 89 if(flag){//如果flag为真,表明账户中已有人存钱进去,存钱方法阻塞 90 wait(); 91 }else{ 92 //执行存款操作 93 System.out.println(Thread.currentThread().getName()+" 存款:" +depositAmount); 94 balance += depositAmount; 95 System.out.println("账户余额为:" + balance); 96 //将账户是否已有存款的旗标设为true 97 flag=true; 98 notifyAll(); 99 100 } 101 }catch (Exception e) { 102 e.printStackTrace(); 103 } 104 } 105 }
Account3
1 /** 2 * @Title: DrawDepositTest3.java 3 * @Package 4 * @author 任伟 5 * @date 2014-12-9 下午2:09:38 6 * @version V1.0 7 */ 8 9 /** 10 * @ClassName: DrawDepositTest3 11 * @Description: 测试存款和取款线程 12 * @author 任伟 13 * @date 2014-12-9 下午2:09:38 14 */ 15 public class DrawDepositTest3 { 16 public static void main(String[] args) { 17 Account3 acct = new Account3("1234567", 0); 18 new DrawThread3("取钱者", acct, 800).start(); 19 new DepositThread3("存钱者甲", acct, 800).start(); 20 new DepositThread3("存钱者乙", acct, 800).start(); 21 new DepositThread3("存钱者丙", acct, 800).start(); 22 } 23 } 24 25 //取款线程 26 class DrawThread3 extends Thread{ 27 private Account3 account; //模拟用户账户 28 private double drawAmount; //取钱数 29 30 public DrawThread3(String name, Account3 account, double drawAmount) { 31 super(name); 32 this.account = account; 33 this.drawAmount = drawAmount; 34 } 35 36 //重复100次执行取钱操作 37 public void run(){ 38 for(int i=0; i<100; i++){ 39 account.draw(drawAmount); 40 } 41 } 42 } 43 44 //春款线程 45 class DepositThread3 extends Thread{ 46 private Account3 account; //模拟用户账户 47 private double depositAmount; //存钱数 48 49 public DepositThread3(String name, Account3 account, double depositAmount) { 50 super(name); 51 this.account = account; 52 this.depositAmount = depositAmount; 53 } 54 55 //重复100次执行存钱操作 56 public void run(){ 57 for(int i=0; i<100; i++){ 58 account.deposit(depositAmount); 59 } 60 } 61 62 63 }
DrawDepositTest3
Result
如图所示的阻塞并不是死锁,取钱者线程已经执行结束,而存款者线程只是在等待其他线程来取钱而已,并不是等待其他线程释放同步监视器。
转载于:https://www.cnblogs.com/renwei/p/4153207.html
多线程总结五:线程通信(一)相关推荐
- C++多线程:Linux 线程通信,唤醒,互斥锁(未完待续)
c++ multi thread message sending and notify 线程通信常用的方法有共享内存和消息传递,推荐使用消息传递. 最常用的就是管道了,可以使用匿名管道或者命名管道. ...
- 深入浅出Win32多线程程序设计之线程通信
简介 线程之间通信的两个基本问题是互斥和同步. 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒. 线程互斥是 ...
- C# 多线程同步和线程通信
多线程通信 1. 当线程之间有先后的依赖关系时,属于线程之间的通信问题.也就是后一个线程要等待别的一个或多个线程全部完成,才能开始下一步的工作.可以使用: WaitHandle Class WaitH ...
- 多线程 4——线程通信、线程池、定时器
多线程 一.线程通信 1.等待集 2.wait()方法 3.notify() / notifyAll()方法 4.等待队列/同步队列 5.生产者消费者模型 二.线程池 1.jdk中的线程池 2.自己实 ...
- Python3进阶--Socket编程、多线程(创建方式、线程通信、线程锁、线程池)
第一章 变量.常用循环体.代码结构.代码练习 第二章 列表.元组等数据结构.字符串驻留机制及字符串格式化操作 第三章 函数.面向对象.文件操作.深浅拷贝.模块.异常及捕获 第四章 项目打包.类和对象高 ...
- Java:多线程(同步死锁、锁原子变量、线程通信、线程池)
5,同步和死锁 5.1,线程同步 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象: 修饰一个方法,被修饰的方法称为同步方法,其作用 ...
- 多线程——线程实现、线程状态、线程同步、线程通信、线程池
多线程 一.线程 1.普通方法调用和多线程 2.程序.进行.线程 二.线程创建 1.继承Thread类 2.实现Runable接口 3.实现Callable接口 4.静态代理模式 5.Lamda表达式 ...
- java 多线程编程(包括创建线程的三种方式、线程的生命周期、线程的调度策略、线程同步、线程通信、线程池、死锁等)
1 多线程的基础知识 1.1 单核CPU和多核CPU 单核CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务.微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那 ...
- 多线程(三)线程通信
线程中断.线程让步.线程睡眠.线程合并的使用推荐翻阅这篇博客:http://blog.csdn.net/ghsau/article/details/17560467 本文主要补充wait(),noti ...
最新文章
- 老板:kill -9的原理都不知道就敢到线上执行,明天不用来了
- Android 使用Jsoup解析Html
- UA MATH636 信息论2 数据压缩
- ATG中的定时Job处理
- linux笔记之 raid
- 技术分享 | 混合云模式下SaaS端前端最佳实践
- C语言中#、##宏定义的用法
- Flash在浏览器里调试获取trace
- cv mat保存图片_EmguCV创建/保存图片
- HP LaserJet P1007 装不到驱动
- linux ip被占用顶掉,记一次 Linux服务器被***后的排查思路
- 对Win10和Linux双系统进行备份
- Windows下硬盘存储情况可视化工具--WinDirStat
- Qt6 tesseract-ocr 截图识字
- python:图片显示
- 初创公司如何布局零信任网络安全?
- 两点之间的最短距离是?
- 杜君立:紧箍咒与纸枷锁
- 计算机CQ,[计算机软件及应用]CQ使用简介.ppt
- 《网络空间测绘技术与实践》正式发售,让网络空间作战“有图可依”
热门文章
- Apache Mahout中推荐算法Slope one源码分析
- 交换机端口隔离技术应用
- 会话技术CookieSession
- 折线分割平面(hdoj 2050,动态规划递推)
- SFB 项目经验-18-三台前端服务器同时停止两台后-前端服务启不来
- Spring Security源码分析十三:Spring Security 基于表达式的权限控制
- 我的第一个python web开发框架(1)——前言
- SQL 解决从分组数据中总是挑选第一条数据的问题
- JAVA的异常(四):finally关键字
- js中event,event.srcElement,event.target在IE和firefox下的兼容性