java并发编程要点

Java并发问题主要有三个核心概念:原子性,可见性,顺序性。

原子性

并发问题的原子性的概念和数据库事务的原子性是一样的:一个操作的多个步骤要么一起生效,要么一起回滚。
java自带的并发控制的手段中,可以保障原子性的有:

  • synchronized 关键字
  • CAS
可见性

可见性的问题是指当变量被多个线程使用时,一个线程对其作出的修改操作,是否后续其他线程读的时候能马上读到修改后的值。可见性问题的产生是因为CPU为了加速数据读取读取的速度,采用了多级的告诉缓存。
java中保障可见性的手段有

  • synchronized关键字
  • volidate关键字
顺序性

顺序指的是代码的执行顺序,顺序性指的是java编译器和CPU,在保障单个线程执行的时代码的逻辑结果不变的前提下,可能会对代码执行顺序的作出的一些改变(优化)。代码块在单线程执行的情况下,不管顺序怎么变,jvm一定会保证其逻辑不变,但是多个线程的情况下如果发生了重排序,则局部的逻辑可能是没变,单是全局的逻辑已经有问题了,比如下面的代码块

class BadlyOrdered {  
  boolean a = false;  
  boolean b = false;  
  void threadOne() {  
    a = true;  
    b = true;  
  }  

  boolean threadTwo() {  
    boolean r1 = b; // sees true  
    boolean r2 = a; // sees false  
    return r1 && !r2; // returns true  
  }  
}  

方法threadOne在单线程执行的情况下,不管顺序怎么变,其最终的结果都是a和b都赋值为true。但是如果是多个线程,线程1执行方法threadOne,线程2执行方法threadTwo,即使不考虑可见性的问题,因为threadOne的执行顺序被排序,所以b的值得先被赋值为true,然后线程2读到了b=true和a=false,最后返回的结果将是true。
那么怎么解决多线程情况下,顺序性带来的不确定问题呢。一种方法是在编码时显示使用synchronized关键,做到同一时间只有1个线程能操作共享的数据。另外一个方法运用jvm自带的happens-before规则。

happens-before

happens-before规则的描述如下

Happens-Before Relationship : Two actions can be ordered by a happens-before relationship.If one action happens before another, then the first is visible to and ordered before the second.

可见,happens-before规则同时对可见性和顺序产生的了影响。happens-before这个名称感觉还是挺有歧义的,从"before"这个字眼上看,以为它定义的是顺序性,其实"before"描述的是可见性的"before"。而顺序性,并不能简单的从字面描述去理解。比如,java规范定义了多条满足的happens-before规则,有一条是:

A write to a volatile field happens-before every subsequent read of that volatile.

它的"before"的定义,不能简单理解为对一个volatile变量的写操作发生在对其读操作之前。一个线程写,一个线程读,jvm可不知道哪个会先执行到。这里的"before"是可见性的before,也就是,一个volatile变量的写操作以及其后面的操作,对另外一个线程的发生在这之后的volatile变量的读操作以及之后的操作可见。
而这条规则,对顺序性的真正的影响是:

  • 禁止把volatile写之前的行为与它重排序
  • 禁止把volatile读之后的行为与它重排序

对于上面的示例程序,只要把变脸b用volatile关键字修饰,那threadOne方法就不会发生重排序了。也就是说happens-before规则也规定哪些类型的操作之间,编译器和CPU不能对其进行重排序,编程的时候只要利用这些内置的规则,就能消除重排序在多线程环境下的问题。
总结来说,顺序性是java为了单线程执行的时候做的优化,但是它会在多线程环境下带来问题,并且这些问题基本是不能在编码阶段做理论分析的。为了解决这个问题,java又自己内置了一些规则(happens-before规则)对重排序做了一些限制,多线程编程的时候,只要利用这些规则,确保我们关心的关键点不会发生重排序,也就保证了程序的正确性。

Lock接口

我们知道Lock是jdk提供的并发控制工具包,使用Lock也能保证java并发的三个重要特性的。但是需要说的Lock只是一个工具包,它提供的保障都是依赖jvm提供的更底层的机制来保障的

  • 可见性: 是对实现中的锁变量使用volidate关键字,然后依赖volidate带来的happen-before特性,保障加锁和解锁之间的修改对其他线程可见的
  • 原子性:Lock本身的加锁解锁这两个行为的原子性是通过CAS操作保障的,而加锁之后的行为的原子性,是通过控制同一时间只能由1个线程执行,逻辑保障的
  • 顺序性: 同原子性,也是通过控制同一时间只能由1个线程执行的保障的
总结
原子性 可见性 顺序性
sychronized 保证 保证 保证
volatile 不保证 保证 部分保证
CAS操作 保证 不保证 不保证
Lock工具类 保证 保证 保证

####### refer
http://www.infoq.com/cn/articles/java-memory-model-2
http://ifeve.com/easy-happens-before/
http://blog.csdn.net/admiral_dota/article/details/50489882

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容