java线程同步——竞争条件的荔枝+锁对象
【0】README
0.1) 本文描述转自 core java volume 1, 源代码为原创,旨在理解 java线程同步——竞争条件的荔枝+锁对象 的相关知识;
0.2) for full source code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter14/ThreadFive.java
【1】竞争条件的荔枝
1.1)某银行有若干个账户(我们这里设置为4个),且初始余额均为10000; 账户间存在着转账操作;
Attention):在模拟这个程序的过程中, 不清楚在某一时刻某银行的账户转账多少钱,但是其总金额应该是不变的, 因为我们所做的一切不过是从银行的一个账户转账到另一个账户(干货——无论怎样转账,总金额应该是不变的,始终为40000)。
对上述运行结果的分析(Analysis):
- A1)问题在于这不是一个原子操作, 该指令可能被如下处理:
- step1)将 account[to] 加载到寄存器;
- step2)增加 amount 到 account[to]上;
- step3)将结果写回 account[to];
- A2)现在线程1 执行step1 + step2, 然后CPU切换到执行线程2;
- A2.1)假设线程2修改了account[to]的值;
- A2.2)之后,线程1被唤醒,然后进行 step3;
- A3)那显然, 线程1的step3操作重写了 线程2的写入结果(线程1擦除线程2所做的更新), 所以就出现了最终的总金额不等于 40000的错误结果;
- A4)如果要保持结果的合理性,只需要达到一个目的,就是将对账户余额的访问加以限制,每次只能有一个线程在访问。这样就能保证账户中余额数据的合理性了。
1.2)解决方法:
- 1.2.1)使用同步块(synchronized):在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。例如:(干货——无论怎样转账,总金额应该是不变的,始终为40000)。
- 1.2.2)使用同步方法:(干货——无论怎样转账,总金额应该是不变的,始终为40000)。
【2】锁对象
2.1)有两种方法防止代码块受并发访问的干扰:
- 2.1.1) synchronized 关键字, 构造同步块,或是同步方法;(如1.2中解决方法 所示)
- 2.1.2) java 5.0 引入的 ReentrantLock 类;
2.2)用ReentrantLock保护代码块的基本结构
myLock.lock()
try
{}
finally
{myLock.unlock()
}
- 2.2.1)这一结构确保了 任何时刻只有一个线程进入临界区域, 一旦一个线程封锁了锁对象,其他任何线程都无法通过lock语句。 当其他线程调用 lock 时, 它们会被阻塞,直到第一个线程释放锁对象;
Warning)把解锁操作包括在了 finally 子句中是至关重要的。 如果在临界区的代码抛出异常, 锁必须被释放, 否则, 其他线程将永远阻塞下去;
Attention)
- A1)锁是可重入的, 因为线程可以重复地获得已持有的锁;
- A2)锁保持一个持有计数来跟踪对 lock 方法的嵌套调用, 线程在每一次调用lock 都要调用 unlock 来释放锁;
- A3)由于这一特性, 被一个锁保护起来的代码可以调用另一个使用相同的锁的方法;
java线程同步——竞争条件的荔枝+锁对象相关推荐
- (删)Java线程同步实现二:Lock锁和Condition
在上篇文章(3.Java多线程总结系列:Java的线程同步实现)中,我们介绍了用synchronized关键字实现线程同步.但在Java中还有一种方式可以实现线程同步,那就是Lock锁. 一.同步锁 ...
- java线程同步——条件对象+synchronized 关键字
[0]README 0.1) 本文描述转自 core java volume 1, 源代码为原创,旨在理解 java线程同步--条件对象+synchronized 关键字 的相关知识: 0.2)for ...
- java线程 同步与异步 线程池
1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成的,有时为了解 决此问题,优先考虑 ...
- (转) Java线程同步阻塞, sleep(), suspend(), resume(), yield(), wait(), notify()
为了解决对共享存储区的访问冲突,Java 引入了同步机制.但显然不够,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个. 为解决访问控制问题,Java ...
- Java --- 线程同步和异步的区别
1. Java 线程 同步与异步 多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成的,有 ...
- java线程同步原理
一. java线程同步原理 java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处理这 ...
- Java线程--同步和异步的区别
本文转自https://blog.csdn.net/u011033906/article/details/53840525 1. Java 线程 同步与异步 多线程并发时,多个线程同时请求同一个资源, ...
- Java线程同步内存实现
Java线程同步内存实现 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可 ...
- java 线程同步的方法_Java多线程同步方法
Java多线程同步方法 package com.wkcto.intrinsiclock; /** * synchronized同步实例方法 * 把整个方法体作为同步代码块 * 默认的锁对象是this对 ...
最新文章
- 自己用C#写一个采集器、蜘蛛(zz)
- vscode安装本地服务器_VS Code安装和远程服务器连接配置
- C语言给定数字n阶乘的末尾计算零个数(附完整源码)
- linux禁用锁定和解除解锁用户账号的方法
- 洛谷p2234/BZOJ1588 [HNOI2002]营业额统计
- python文本文件不能用二进制文件方式读入_如何使用python函数以二进制形式读取文件?...
- Python笔记-字符串转json
- 作为一个生鲜电商自媒体
- linux 查看usb端口_linux开发:Linux下查看端口占用
- 基于SSM的企业工资管理系统
- 一文掌握秩和比综合评价法
- 腾讯C++程序员面试题
- 清华大学超级计算机中心,中国科学技术大学超级计算中心
- 80psi等于多少kpa_关于胎压的换算psi、bar,kpa
- 搭建一个 nodejs 脚手架
- Spring Security 4 使用@PreAuthorize,@PostAuthorize, @Secured, EL实现方法安全(带源码)
- 通过搜狐微博API,发带图片的微博
- pandas基础用法详解
- 英文歌曲:my heart will go on(我心永恒)
- 熬秃了头整理的网络工程师学习笔记和心得:传闻中的OSPF到底是什么
热门文章
- Saving Beans HDU - 3037(卢卡斯定理)
- [2-sat专练]poj 3683,hdu 1814,hdu 1824,hdu 3622,hdu 4115,hdu 4421
- CF802O-April Fools‘ Problem(hard)【wqs二分,优先队列】
- P3172-[CQOI2015]选数【dp,容斥】
- bzoj1013,luogu4035-[JSOI2008]球形空间产生器【高斯消元】
- P1038-神经网络【拓扑排序】
- ssl初一组周六模拟赛【2018.3.17】
- codeforces1438 E.Yurii Can Do Everything
- 【DP】平铺方案(ybtoj DP-1-5)
- [XSY3382] 专家系统(二分+线段树)