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

【0】README

0.1) 本文描述转自 core java volume 1, 源代码为原创,旨在理解 java线程同步——条件对象+synchronized 关键字 的相关知识;
0.2)for full source code : https://github.com/pacosonTang/core-java-volume/blob/master/chapter14/SynchBank.java


【1】条件对象

1.1)为什么引入条件对象:通常,线程进入临界区, 却发现在某一条件满足后它才能执行, 要使用一个条件对象来管理那些已经获得了一个锁但是却不能做有用工作的线程;
1.2)看个荔枝:

  • 1.2.1)我们避免选择没有足够资金的账户作为转出账户:
if(bank.getBalance(from) >= amount)bank.transfer(from, to, amount)
  • 1.2.2)当前线程有可能在 调用 transfer之前就被CPU切断了
if(bank.getBalance(from) >= amount) // thread might be deactived at this pointbank.transfer(from, to, amount)
  • 1.2.3)我们必须要确保: 没有其他线程在本检查余额 与转账活动间修改余额。通过使用锁保护来支持这一点:
    这里写图片描述

1.3)一个锁对象可以有一个或多个条件对象。 你可以使用 newCondition 方法获得一个条件对象;

  • 1.3.1)如果transfer 发现余额不足,它可以调用:
suffcientFunds.await(); 使得当前线程阻塞了,并放弃锁;(干货——为了避免死锁+await方法的作用)

1.4)等待获得锁的线程和调用 await 方法的线程存在本质的不同:

  • 1.4.1)一旦一个线程调用 await 方法, 它进入该条件的等待集, 当锁可用时,该线程不能马上解除阻塞;
  • 1.4.2)相反,它处于阻塞状态, 直到另一个线程调用同一个条件上的signalAll 方法为止, 这一调用重新激活 因为这一条件而等待的所有线程;
  • 1.4.3)一旦锁成为可用的, 它们中的某个将从 await 方法调用返回, 获得该锁并从阻塞的地方继续执行;

1.5)容易造成死锁:(干货)

  • 1.5.1)原因: 当一个线程调用 await 方法时, 它没有办法重新激活自身。 它寄希望于其他线程,然而,如果最后一个活动线程在解除其他线程的阻塞状态之前就调用了 await 方法, 那么它就 被阻塞了, 这将导致所有的线程都处于阻塞状态,导致死锁;
  • 1.5.2)解决方法:应该何时调用 signalAll 方法呢?经验上讲, 在对象的状态有利于等待线程的方法改变时调用 signalAll方法;

Attention)

  • A1)注意, 调用 signalAll 不会立即激活一个等待线程, 它仅仅解除等待线程的阻塞,以便这些线程可以在当前线程退出同步方法后, 通过竞争实现对对象的访问;(干货——signalAll方法的作用)
  • A2)另一个方法 signal: 则是随机解除等待集中某个线程的阻塞状态,这比解除所有线程的阻塞更加有效, 但也存在危险;(干货——signal 方法的作用)

Warning)

  • W1)当一个线程拥有某个条件的锁时,它仅仅可以在该条件上调用 await, signalAll 或 signal 方法;
  • W2)即是, 一个系统中有多个条件变量(Condition), 每个条件上等待的线程不同, 某条件下的线程只唤醒该条件下的等待进程;
    这里写图片描述

【2】synchronized 关键字

2.1)总结一下有关锁和条件的关键之处:

  • 2.1.1)锁用来保护代码片段, 任何时刻只能有一个线程执行被保护的代码;
  • 2.1.2)锁可以管理试图进入被保护代码段的线程;
  • 2.1.3)锁可以拥有一个或多个相关的条件对象;
  • 2.1.4)每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程;

2.2) Lock 和 Condition 接口专门为 程序设计人员提供了 高度的锁定控制;
2.3)synchronized 关键字: 可用于定义 同步方法和 同步块以保护这个方法或同步块中的代码 在同一时间只能被一个线程访问;
2.4)wait 方法添加一个线程到等待集中, notifyAll/notify 方法解除等待线程的阻塞状态;

  • 2.4.1)换句话说: 调用wait 和 notifyAll 方法 等价于 condition.await() 和 condition.signalAll() 方法;

Annotation)

  • A1) wait, notifyAll , notify 方法是 Object的final方法;
  • A2) await, signalAll, signal 方法 是Condition 接口的方法, 以便与上述方法不会发生冲突;
    这里写图片描述

2.5) 内部锁和条件存在一些局限:

  • 2.5.1)不能中断一个正在试图获得锁的过程;
  • 2.5.2)试图获得锁时不能设定超时;
  • 2.5.3)每个锁仅有单一条件,可能是不够的;

2.6)在代码中应该使用哪一种? Lock 和 Condition 对象还是同步方法?下面是建议:

  • 2.6.1)最好既不用 Lock/Condition 也不用 synchronized关键字; 在许多case 下,你可以使用 java.util.concurrent 包中的一种机制, 它会为你处理所有的加锁。 你会看到如何使用阻塞队列来不同完成一个共同任务的线程; (干货——阻塞队列的作用)
  • 2.6.2)如果 synchronized关键字适合, 请尽量使用它;
  • 2.6.3)如果特别需要 Lock/Condition 结构提供的独有特性, 才使用 Lock/Condition;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hibernate之必须导入jar包

Hibernate必须导入的包 hibernate是ORM的解决方案,其底层对数据库的操作依赖于JDBC,所以必须先取得JDBC驱动程序,在这使用的是MySQL,所以必须至先取得MySQL的JDBC驱动程序 https://dev.mysql.com/downloads/connector/j/ Hibern…

赞扬别人团建评论_赞扬精心设计:基于属性的测试如何帮助我成为更好的开发人员...

赞扬别人团建评论开发人员的测试工具箱就是其中之一,很少保持不变。 可以肯定的是,一些测试实践已被证明比其他测试更有价值,但是,我们仍在不断寻找更好,更快和更具表现力的方法来测试我们的代码。 基于属性的测试 是 …

linux c read函数返回值,Linuxc - GNU Readline 库及编程简介

GNU Readline 库及编程简介简介用过 Bash 命令行的一定知道,Bash 有几个特性:TAB 键可以用来命令补全↑ 或 ↓ 键可以用来快速输入历史命令还有一些交互式行编辑快捷键:C-A / C-E 将光标移到行首/行尾C-B / C-F 将光标向左/向右移动一个位置C…

java泛型——桥方法

【0】README 0.1)以下内容转自: http://www.cnblogs.com/ggjucheng/p/3352519.html 【1】泛型约束和局限性—— 类型擦除所带来的麻烦 1.1)继承泛型类型的多态麻烦。(—— 子类没有覆盖住父类的方法 ) 看看下面这个…

Hibernate框架之入门配置

一、Hibernate导入相关的包参考:http://blog.csdn.net/tunni/article/details/54982160这些包包括相应数据库驱动、hibernate.zip下lib目录下的jar包,其中必须包是required目录下的.jar二、在项目classpath(类路径,即src目录下&am…

annotations_Spring Annotations我从来没有机会使用第2部分:@ConfigurationProperties

annotations几天前,我在检查其他内容时不小心偶然发现了Spring Boot项目中的Spring注释。 我们都知道如何将带有“ Value”的属性值绑定到类,并且我们都知道如果要绑定多个属性,这可能会很麻烦。 Spring Boot可以为您提供帮助。 您可以使用“…

linux下检测硬盘,【转载】linux下硬盘监控诊断工具SmartTools

对于windwos下raid卡具备告警功能,当硬盘故障、raid卡告警时,可以发邮件给管理员。IBM、HP、Dell都支持。但在linux下,就没有找到相关的好工具了,今天到陈沙克的博客上到一篇关于linux下硬盘监控诊断工具SmartTools,感…

hibernate框架之主键生成

一、 hibernate 框架中主键的生成策略 (1)native: 表示由设置的方言决定采用什么数据库生成主键方式,根据底层数据库能力选择identity、sequence中的一个。 例如:在MySQL中会采用自增长的方式,主键字段必须都是整形类型;在Oracle数…

java泛型通配符

【0】README 0.1)以下内容转自: http://blog.csdn.net/baple/article/details/25056169 0.2) T 有类型 ? 未知类型 一、通配符的上界(extends关键字) 既然知道List并不是List的子类型,那就需…

jdk 1.8 内存可见性_JDK 14中的常规,安全和确定性外部内存访问

jdk 1.8 内存可见性在“ JDK 14 Rampdown:Build 27 ”一文中,我总结了JDK 14 Early Access Build #27中新增的许多针对JDK 14的功能。 已经存在另一种JDK 14 Early Access Build,并且此[ Build 28(2019/12/18&#xff…

linux开启防火墙ping,如何在防火墙中放开ping

如何在防火墙中放开ping操作时需要注意的几项:1,注意iptables各版本间的区别我们的server os最旧的版本是redhat 7.3 kernel是2.4.20-18.7最新的server os最新的版本是centos 5, kernel是2.6.18-8差距很大iptables以模块形式运行在内核的空间,用lsmod可以看到所以它与内核的版本…

Hibernate: You have an error in your SQL syntax; check the manual that corresponds to your MySQL

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ...Hibernate 出现这样的错误是因为表中的字段名使用了sql的保留字,不要使用保留字 一、mysql的保留字主要有&#xff1…

java.io 包

java.io 通过数据流、序列化和文件系统提供系统输入和输出。 请参见: 接口摘要CloseableCloseable 是可以关闭的数据源或目标。DataInputDataInput 接口用于从二进制流中读取字节,并根据所有 Java 基本类型数据进行重构。DataOutputDataOutput 接口用…

linux系统怎么安装pr,Linux安装后的配置

系统:CentOS-6.31.NVIDIA驱动的安装与配置Linux本身的显卡驱动是能够满足平常应用的,但是有时候我们为了获得3D效果,或者更流畅的视频体验,我们会安装新的显卡驱动。这时候就需要安装闭源驱动了,个人认为闭源的驱动更为好一些&…

java第三阶段源代码_有效Java第三版的源代码已更新为使用较新的功能

java第三阶段源代码那些已经阅读了有效Java 第三版的人可能知道与该书相关的源代码可以在GitHub上获得 。 jbloch / effective-java-3e-source-code项目拥有1700多个星星,截至撰写本文时,它已被分叉了近800次。 在有效Java的第三版中, Java的…

《线性代数及其应用》

【0】README 0.1)以下内容转自: http://blog.csdn.net/ljbkiss/article/details/7194719 【1】正文干货 1.1) 断断续续的终于把 《线性代数及其应用(Linear Algebra and Its Application) David C.Lay》 这本书看完了…

micrometer_具有InlfuxDB的Spring Boot和Micrometer第1部分:基础项目

micrometer对于那些关注此博客的人来说,难怪我会经常使用InfluxDB。 我喜欢这样一个事实,它是一个真正的单一用途的数据库(时间序列),具有许多功能,并且还带有企业支持。 Spring也是我选择的工具之一。 因…

如何在win7(xp)home version下安装 rose 32 bit

【0】README 0.1) 以下部分内容转自 http://blog.csdn.net/encienqi/article/details/5578725 【1】 干货开始 如果是家庭版(win7 or WindowsXPHomeEdition)请先按以下步骤修改部分文件后再安装: 1.1)安装Microsoft Orca工具 step1&#x…

接口 Closeable

java.io 接口 Closeable public interface Closeable Closeable 是可以关闭的数据源或目标。调用 close 方法可释放对象保存的资源(如打开文件)。 从以下版本开始:1.5方法摘要 void close() 关闭此流并释放与此流关联的所有系统资源。 方法详…

Linux下python包放在哪,在alpinlinux中使用apk安装的Python包

我想用apk在Alpine Linux中安装一些Python包。我用numpy作为下面的例子。文档文件FROM python:3-alpineRUN apk add --update py3-numpy我建立我的码头形象$ docker build -t python-numpy .Sending build context to Docker daemon 2.048kBStep 1/2 : FROM python:3-alpine---…