【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线程同步——竞争条件的荔枝+锁对象相关推荐

  1. (删)Java线程同步实现二:Lock锁和Condition

    在上篇文章(3.Java多线程总结系列:Java的线程同步实现)中,我们介绍了用synchronized关键字实现线程同步.但在Java中还有一种方式可以实现线程同步,那就是Lock锁. 一.同步锁 ...

  2. java线程同步——条件对象+synchronized 关键字

    [0]README 0.1) 本文描述转自 core java volume 1, 源代码为原创,旨在理解 java线程同步--条件对象+synchronized 关键字 的相关知识: 0.2)for ...

  3. java线程 同步与异步 线程池

    1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成的,有时为了解 决此问题,优先考虑 ...

  4. (转) Java线程同步阻塞, sleep(), suspend(), resume(), yield(), wait(), notify()

    为了解决对共享存储区的访问冲突,Java 引入了同步机制.但显然不够,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个. 为解决访问控制问题,Java ...

  5. Java --- 线程同步和异步的区别

    1. Java 线程 同步与异步 多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成的,有 ...

  6. java线程同步原理

    一. java线程同步原理 java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处理这 ...

  7. Java线程--同步和异步的区别

    本文转自https://blog.csdn.net/u011033906/article/details/53840525 1. Java 线程 同步与异步 多线程并发时,多个线程同时请求同一个资源, ...

  8. Java线程同步内存实现

    Java线程同步内存实现 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可 ...

  9. java 线程同步的方法_Java多线程同步方法

    Java多线程同步方法 package com.wkcto.intrinsiclock; /** * synchronized同步实例方法 * 把整个方法体作为同步代码块 * 默认的锁对象是this对 ...

最新文章

  1. 自己用C#写一个采集器、蜘蛛(zz)
  2. vscode安装本地服务器_VS Code安装和远程服务器连接配置
  3. C语言给定数字n阶乘的末尾计算零个数(附完整源码)
  4. linux禁用锁定和解除解锁用户账号的方法
  5. 洛谷p2234/BZOJ1588 [HNOI2002]营业额统计
  6. python文本文件不能用二进制文件方式读入_如何使用python函数以二进制形式读取文件?...
  7. Python笔记-字符串转json
  8. 作为一个生鲜电商自媒体
  9. linux 查看usb端口_linux开发:Linux下查看端口占用
  10. 基于SSM的企业工资管理系统
  11. 一文掌握秩和比综合评价法
  12. 腾讯C++程序员面试题
  13. 清华大学超级计算机中心,中国科学技术大学超级计算中心
  14. 80psi等于多少kpa_关于胎压的换算psi、bar,kpa
  15. 搭建一个 nodejs 脚手架
  16. Spring Security 4 使用@PreAuthorize,@PostAuthorize, @Secured, EL实现方法安全(带源码)
  17. 通过搜狐微博API,发带图片的微博
  18. pandas基础用法详解
  19. 英文歌曲:my heart will go on(我心永恒)
  20. 熬秃了头整理的网络工程师学习笔记和心得:传闻中的OSPF到底是什么

热门文章

  1. Saving Beans HDU - 3037(卢卡斯定理)
  2. [2-sat专练]poj 3683,hdu 1814,hdu 1824,hdu 3622,hdu 4115,hdu 4421
  3. CF802O-April Fools‘ Problem(hard)【wqs二分,优先队列】
  4. P3172-[CQOI2015]选数【dp,容斥】
  5. bzoj1013,luogu4035-[JSOI2008]球形空间产生器【高斯消元】
  6. P1038-神经网络【拓扑排序】
  7. ssl初一组周六模拟赛【2018.3.17】
  8. codeforces1438 E.Yurii Can Do Everything
  9. 【DP】平铺方案(ybtoj DP-1-5)
  10. [XSY3382] 专家系统(二分+线段树)