并发--Java线程内存模型

多任务处理,在计算机硬件上的问题

1. 缓存一致性

计算机中,CPU的运行速度和内存的读取速度,有几个数量级的差异; 为了解决这个问题, 现代计算机在CPU和内存之间,都加入了和CPU运算速度匹配的高速缓存Cache; 运算时, 先将数据读入cache, CPU从缓存中读取数据, 运算结束后, CPU将结果写入缓存, 然后再由缓存把数据写回内存; 基于高速缓存的方案解决了CPU与内存之间的数速度矛盾, 但是同时引进了一个新问题: 内存一致性; 如果多个CPU单元同时处理同一块内存区域的数据, 可能各个CPU的缓存数据不一样, 那这个时候把数据写回内存, 要怎么处理?

2. 指令重排优化

CPU为了尽可能的提升效率,会对输入代码进行乱序执行优化,然后将结果重组,保证结果和顺序执行是一样的, 但是并不保证代码中各个语句执行顺序和输入的代码一致, 因此代码的顺序并不能保证执行的顺序; Java即时编译中,也有 指令重排优化, 因此, 如果一个计算任务依赖另外一个计算任务的中间结果时, 需要去避免重排造成的问题;

Java内存模型(Java Memory Model, JMM)

1. 主内存和工作内存

Java内存模型规定了, 代码运行的所有变量都存储在主内存中 , 同时, 每条线程还有自己的工作内存, 线程的工作内存中包含了被该线程使用的线程私有变量 和主内存副本 ,线程对变量的所有操作(读取,赋值等)都是在工作线程进行, 不能直接读写主内存中的变量; 主内存包含对象实例数据,静态字段数据等, 线程私有变量主要是局部变量和方法参数;

2. 内存间交互操作

主内存和工作内存之间的相互操作, 即变量如何从主内存中读入到工作内存, 代码执行引擎如何使用, 如何从工作内存写回主内存; Java内存模型定义了8种操作来实现, 并且虚拟机实现时, 这8种操作必须都是原子的,不可再分;

  • lock: 用于主内存,把一个变量标记为某条线程独占状态
  • unlock: 用于主内存, 把处于lock的变量释放出来, 释放出来后变量才可以被其他线程lock
  • read: 用于主内存, 把变量从主内存传输到工作内存, 方便后续的load使用
  • load: 用于工作内存, 把从主内存中read的变量放入工作内存的变量副本中
  • use: 用于工作内存, 把工作内存的变量传递给执行引擎去使用; 虚拟机需要使用变量时,执行此操作
  • assign: 用于工作内存, 把从执行引擎收到的值, 赋值给工作内存中的变量; 虚拟机遇到变量赋值语句时,执行此操作
  • store: 用于工作内存, 把工作内存中的变量传回到主内存, 以便后续的write操作
  • write: 用于主内存, 把store操作的变量写入到主内存

内存模型与线程安全

并发过程中实现线程安全, 通常是要保证代码块是原子的,有序执行的, 同时共享变量的修改对线程都是可见的; 而Java内存模型也是围绕着并发过程中, 如何处理原子性, 可见性, 有序性这3个特征来建立的;

原子性(Atomicity)

Java内存模型中, read,load,use,assign,store,write都是原子性操作, 因此, 对于基本数据类型的读写访问,都可以认为是具有原子性的, (内存模型允许对long,double这类64位的数据读写操作, 划分成两次32位的操作来进行,因此对64位数据的操作可能不具有原子性, 但是目前的虚拟机实现,都是把这类64位数据作为原子性操作);
如果需要大范围的保证原子性, 内存模型中的lock和unlock可以实现; 虽说虚拟机对内存的lock和unlock并没开放给用户, 但提供了更高层次的指令, 反应到Java代码中就是同步块--synchronize关键字, 和java.util.concurrent.locks.Lock的操作, 因此在synchronize代码块及Lock.lock和unlock之间的代码块也具有原子性

可见性(Visibility)

可见性是指当一个线程修改了共享变量的值, 其他线程能够立即得知这个修改
volatile修饰的变量,每次修改后,都会立即同步到主内存,每次使用时,都会去从主内存刷新,因此, volatile修饰的变量在多线程时保证了可见性;
除volatile之外, 同步块和final关键字也能实现可见性; 同步块的可见性, 是由Java内存模型中,对变量执行unlock操作,必须将变量同步回主内存这一规则保证的; final的可见性是指: final修饰的字段,一旦初始化完成,在其他线程就都能看见final字段的值,并且不可修改;

有序性(Ordering)

Java的volatile关键字和代码的同步块可以保证有序性;
volatile关键字本身包含了禁止指令重排的语意;
同步块的有序性, 是由Java内存模型中,一个变量在同一时刻,只允许一条线程对其进行lock操作的规则保证的, 这一规则决定了持有同一个锁的多个同步块只能串行进入;

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

推荐阅读更多精彩内容