文档章节

2017-09-08-Java并发笔记之 Race Condition and Critical Section

kailuncen
 kailuncen
发布于 2017/09/08 11:48
字数 1006
阅读 10
收藏 0

个人介绍

Java爱好者,个人网站: http://kailuncen.me/about/

前言

这几天学习并发编程,race-conditions-and-critical-sections,翻译一下,写点自己的笔记并加上点个人的理解。

网页中里中提到两个名词Race Condition 和 Critical Section,接下来对他们进行解释和例子演示。

Race Condition

在多线程场景下,当多个线程访问同一块资源,且执行结果与线程访问的先后顺序相关,即表明这里面存在着Race Condition,中文翻译即竞争条件。

看下面👇的代码,多个线程都会调用add方法对同一个count值进行加法。

  public class Counter {

     protected long count = 0;

     public void add(long value){
         this.count = this.count + value;
     }
  }

然而,add方法中的加法需要好几个步骤才能完成。

1. 从内存中读取count的值到寄存器。
2. 加value。
3. 写回内存。

如果有两个线程都对add方法进行了操作,比如线程A加3,线程B加2,我们的预期结果是5。由于线程的访问顺序以及切换的时间是不可预期的,在特定的访问顺序下,可能出现一些出乎意料的结果,比如下文中的执行顺序。

A:  Reads this.count into a register (0)
B:  Reads this.count into a register (0)
B:  Adds value 2 to register
B:  Writes register value (2) back to memory. this.count now equals 2
A:  Adds value 3 to register
A:  Writes register value (3) back to memory. this.count now equals 3

由于加法不是原子性的,在加法执行过程中的每一步都可能存在着线程切换。 比如线程A和B都先后读到0,然后线程B占用了时间片完成了加2的操作,写回了内存,此时内存中count的值等于2。 然后线程A重新得到调度,此时线程A内部的count值还是0,线程A对主内存内count的变化是不可见的,然后线程完成加3操作,写回内存,此时count值等于3。

上述代码中的add方法内部就存在着竞争条件,会根据线程执行顺序的不确定性影响最后的执行结果。

Critical Section

我们把会导致Race Condition的区域称为Critical Section,中文翻译临界区。临界区即每个线程中访问临界资源的那段代码。

在上文的代码中,this.count就是临界资源

this.count = this.count + value

就是临界区,为了保证执行结果的正确性,避免临界区内产生竞争条件,我们需要确保临界区内的执行是原子的,每次仅允许一个线程进去,进入后不允许其他线程进入。

我们可以采用线程同步做到以上的要求,线程同步可以使用synchronized同步代码,或者locks,或者是原子变量比如AtomicInteger等。

可以把整个临界区使用synchronized同步,但把临界区拆分成多个小的临界区能够降低对共享资源的争夺,增加整个临界区的吞吐量,下面举个例子。

public class TwoSums {
    
    private int sum1 = 0;
    private int sum2 = 0;
    
    public void add(int val1, int val2){
        synchronized(this){
            this.sum1 += val1;   
            this.sum2 += val2;
        }
    }
}

在上述代码中,简单的做法就是锁住整个对象,只有一个线程能够执行两个不同变量的加法操作。然而,由于这两个变量是互相独立的,可以拆分到两个不同的synchronized块中。

public class TwoSums {
    
    private int sum1 = 0;
    private int sum2 = 0;

    private Integer sum1Lock = new Integer(1);
    private Integer sum2Lock = new Integer(2);

    public void add(int val1, int val2){
        synchronized(this.sum1Lock){
            this.sum1 += val1;   
        }
        synchronized(this.sum2Lock){
            this.sum2 += val2;
        }
    }
}

改动后,两个线程可以同时在add方法中操作,一个线程在第一个synchronized块,另一个线程在第二个synchronized块,两个synchronized块同步的是不同的对象,所以两个线程可以独立执行,整体线程等待的时间会变少,吞吐量能够得到提升。

© 著作权归作者所有

共有 人打赏支持
kailuncen
粉丝 88
博文 17
码字总数 28778
作品 0
卢湾
后端工程师
读书笔记之《Java并发编程的艺术》-java中的锁

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
0
kernel BUG at fs/xfs/xfs_aops.c:1062!

转自: https://bugs.centos.org/view.php?id=14073 RHEL7: kernel crash in xfsvmwritepage - kernel BUG at fs/xfs/xfs_aops.c:1062! SOLUTION VERIFIED - Updated August 17 2017 at 3:52......

jia_xiaolei
07/11
0
0
【转】15个顶级Java多线程面试题及回答

Java 线程面试问题   在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务...

一只死笨死笨的猪
2014/09/30
0
0
读《深入理解Java虚拟机》- 笔记08

《深入理解Java虚拟机:JVM高级特性与最佳实践》第2版 第10章 早期(编译期)优化 59. 语法糖 在计算机语言中添加某种语法,对语言的功能没有影响,但是方便开发人员使用。 泛型是一种语法糖...

阿历Ali
08/18
0
0
15个顶级Java多线程面试题及回答

Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务中多...

LCZ777
2014/05/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

linux 系统的运行级别

运行级别 运行级别 | 含义 0 关机 1 单用户模式,可以想象为windows 的安全模式,主要用于修复系统 2 不完全的命令模式,不含NFS服务 3 完全的命令行模式,就是标准的字符界面 4 系统保留 5 ...

Linux学习笔记
今天
1
0
学习设计模式——命令模式

任何模式的出现,都是为了解决一些特定的场景的耦合问题,以达到对修改封闭,对扩展开放的效果。命令模式也不例外: 命令模式是为了解决命令的请求者和命令的实现者之间的耦合关系。 解决了这...

江左煤郎
今天
2
0
字典树收集(非线程安全,后续做线程安全改进)

将500W个单词放进一个数据结构进行存储,然后进行快速比对,判断一个单词是不是这个500W单词之中的;来了一个单词前缀,给出500w个单词中有多少个单词是该前缀. 1、这个需求首先需要设计好数据结...

算法之名
昨天
12
0
GRASP设计模式

此文参考了这篇博客,建议读者阅读原文。 面向对象(Object-Oriented,OO)是当下软件开发的主流方法。在OO分析与设计中,我们首先从问题领域中抽象出领域模型,在领域模型中以适当的粒度归纳...

克虏伯
昨天
0
0
Coding and Paper Letter(四十)

资源整理。 1 Coding: 1.Tomislav Hengl撰写的非官方作者指南:Michael Gould•Wouter Gerritsma。 UnofficialGuide4Authors 2.R语言包rwrfhydro,社区贡献的工具箱,用于管理,分析和可视化...

胖胖雕
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部