2019独角兽企业重金招聘Python工程师标准>>>

「 ***盛年不重来,一日难再晨,及时当勉励,岁月不待人。***」  陶渊明

PS: 如果觉得本文有用的话,请帮忙点赞,留言评论支持一下哦,您的支持是我最大的动力!谢谢啦~

我们已经知道同步代码块和同步方法可以保证以原子的方式执行,其实,同步还有另外一个重要概念:内存可见性。换句话说,我们不仅希望防止某个线程正在使用对象状态而另一个线程同时在修改状态,而且希望确保当一个线程修改了对象的状态后,其他线程能够看到修改后的状态。

#可见性 一个线程对共享变量值的修改,能够及时的被其他线程看到。可见性微妙的,这是因为可能发生错误的事情总是与直觉大相径庭。来看下面这个例子和他的执行结果:

public class NoVisibility {private static boolean ready;private static int number;private static class ReaderThread extends Thread {public void run() {while(!ready)Thread.yield();System.out.println(number);}}public static void main(String[] args) {// TODO Auto-generated method stubnew ReaderThread().start();number = 88;ready = true;}
}

上面的代码清单,亲测执行的结果是88。 然而,书本上的解释是可能出现错误的结果。错误的结果有下面两种情况(我重现不到下面的结果):

  1. NoVisibility 可能会一直保持循环,因为对读线程来说,主线程写给 ready 的值可能永远对读线程不可见。
  2. NoVisibility 可能会打印0,因为早在对 number 赋值之前,主线程就已经写入 ready 并使之对读线程可见,这是一种重排序。

即可亲测没有发生,但是可能会发生。为了防止这种现象的发生,只能通过对共享变量进行恰当的同步。

####Java 内存模型(JMM,Java Memory Model) 描述了 java 程序中各种变量(线程共享变量)的访问规则,以及在 JVM 中将变量存储到内存和从内存中读取出变量的底层细节。

所有变量都存储在主内存中,每个线程都有自己独立的工作内存,里面保存该线程使用到的变量副本,即主内存中该变量的一份拷贝。

线程对共享变量的所有操作必须在自己的工作内存,线程间变量值的传递需要通过主内存来完成。

####加锁与可见性 加锁的含义不仅仅局限于互斥行为,还包括内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作都必须在同一个锁上同步。

当线程 B 执行有锁保护的代码块时,可以看到线程 A 之前在同一个同步代码块中所有的操作结果。这就是为啥要求所有线程在同一个锁上同步,为了确保某个线程写入该变量的值对于其他线程来说是可见的。

####非原子的64位操作 JVM 允许将64位的读操作或写操作分解为两个32位的操作。Java 中的 long 类型和 double 类型是64位的,所以当读取一个非 volatile 类型的 long 变量时,如果该变量的读操作和写操作在不同的线程中执行,那么很可能会读取到某个值的高32位和另一个值的低32位。因此,在多线程中使用共享的可变的 long 和 double 类型变量时不安全的,除非用关键字 volatile 来声明他们,或者用锁保护起来。

####volatile变量 Java 提供了一种稍弱的同步机制,即 volatile 变量,用来确保将变量的更新操作通知到其他线程。volatile 变量具有 synchronized 的可见性,但是不具备原子特性。要使 volatile 变量提供理想的线程安全,必须同时满足下面两个条件:

  • 对变量的写操作不依赖于自身当前值
  • 该变量没有包含在具有其他变量的不变式中

volatile 通常被当做标识完成、中断、状态的标记使用。典型应用如下代码,检查状态标记,以确定是否退出一个循环。

volatile boolean asleep;while(!asleep)countSomeSheep();

当然,上面也可以用锁,但是会让代码变得复杂。volatile 变量不会加锁,也就不会引起线程的阻塞,相比 sychronized, 这只是轻量级的同步机制。尽管 volatile 也可以用来标识其他类型的状态信息,但是要格外小心。比如, volatile 的语义不足以使自增操作(count++)原子化。

本文原创首发于微信公众号 [ 林里少年 ],欢迎关注第一时间获取更新。

转载于:https://my.oschina.net/seaicelin/blog/1823595

[Java并发编程实战] 共享对象之可见性相关推荐

  1. JAVA并发编程实战——共享对象

    目录 思维导图 1. 可见性 1. 1 过期数据 1.2 锁和可见性 1.3 Volatile变量 2. 发布和逸出 2.1 安全构建实践 3. 线程封闭 3.1 栈限制 3.2 ThreadLoca ...

  2. java单线程共享,「Java并发编程实战」之对象的共享

    前言 本系列博客是对<Java并发编程实战>的一点总结,本篇主要讲解以下几个内容,内容会比较枯燥.可能大家看标题不能能直观的感受出到底什么意思,这就是专业术语,哈哈,解释下,术语(term ...

  3. Java并发编程实战笔记2:对象的组合

    设计线程安全的类 在设计现车让安全类的过程之中,需要包含以下三步: 找出构成对象状态的所有变量 找出约束状态变量的不变性条件 建立对象状态的并发访问策略 实例封闭 通过封闭机制与合适的加锁策略结合起来 ...

  4. 《java并发编程实战》- 关于this引用溢出

    书中3.2中关于this引用溢出例子: 隐式地使this引用逸出(不要这么做): public class ThisEscape {public ThisEscape(EventSource sour ...

  5. 【极客时间】《Java并发编程实战》学习笔记

    目录: 开篇词 | 你为什么需要学习并发编程? 内容来源:开篇词 | 你为什么需要学习并发编程?-极客时间 例如,Java 里 synchronized.wait()/notify() 相关的知识很琐 ...

  6. Java并发编程实战之互斥锁

    文章目录 Java并发编程实战之互斥锁 如何解决原子性问题? 锁模型 Java synchronized 关键字 Java synchronized 关键字 只能解决原子性问题? 如何正确使用Java ...

  7. 《Java 并发编程实战》--读书笔记

    Java 并发编程实战 注: 极客时间<Java 并发编程实战>–读书笔记 GitHub:https://github.com/ByrsH/Reading-notes/blob/maste ...

  8. Java并发编程实战_不愧是领军人物!这种等级的“Java并发编程宝典”谁能撰写?...

    前言 大家都知道并发编程技术就是在同一个处理器上同时的去处理多个任务,充分的利用到处理器的每个核心,最大化的发挥处理器的峰值性能,这样就可以避免我们因为性能而产生的一些问题. 大厂的核心负载肯定是非常 ...

  9. java并发编程实战学习(3)--基础构建模块

    转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...

最新文章

  1. Rman duplicate数据库复制(单系统)
  2. seo日常工作表_专业SEOer的日常工作状态
  3. lua学习笔记之日期时间
  4. 机器学习算法与Python实践之(六)二分k均值聚类
  5. bread是可数还是不可数_不可数名词用法详解,小小名词大作用,英语想打好基础必学的词性...
  6. 通过调用门进行控制转移 ——《x86汇编语言:从实模式到保护模式》读书笔记29
  7. c语言为什么数据写不进文件,求大神看看为什么不能将数据写入文件
  8. 小技巧:with用法 pycharm控制台输出带颜色的文字 打印进度条的
  9. leetcode算法刷题记录表
  10. 用力和应变片计算弹性模量_实验力学实验讲义(08.9).doc
  11. 牛客练习赛60 ~ 斩杀线计算大师
  12. Django 2.0 学习(20):Django 中间件详解
  13. 6-4 二叉树的非递归遍历 (25分)_本周小结!(二叉树)
  14. 人生是什么?——感悟2:绝望时候要相信自己
  15. HBase伪分布式搭建
  16. cad调了比例因子没反应_CAD教程:自由缩放命令的操作流程
  17. 巴塞罗那2019-20赛季球队大名单
  18. android 自适应图片轮播,Android使用Recyclerview实现图片轮播效果的方法
  19. java Calendar日历类
  20. 微程序控制器基本概念及其工作过程

热门文章

  1. php 处理html,PHP解析HTML代码
  2. java图形界面猜字游戏,java程序,猜字游戏,希望大神帮忙
  3. 学习笔记(二)——CSS基础
  4. 阿里巴巴开源分布式框架Seata TCC模式深入分析
  5. docker安装redmine步骤
  6. Android底层禁用WiFi和蓝牙功能
  7. pyqt5教程10:Widgets2组件
  8. 微信小程序-canvas绘制文字实现自动换行
  9. pip和conda批量导出、安装第三方依赖库(requirements.txt)
  10. Object.create()方法