【Java并发编程】:内存可见性
加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性。我们不仅希望防止某个线程正在使用对象状态而另一个线程在同时修改该状态,而且还希望确保当一个线程修改了对象状态后,其他线程能够看到该变化。而线程的同步恰恰也能够实现这一点。
内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果。为了确保所有的线程都能看到共享变量的最新值,可以在所有执行读操作或写操作的线程上加上同一把锁。下图示例了同步的可见性保证。
当线程A执行某个同步代码块时,线程B随后进入由同一个锁保护的同步代码块,这种情况下可以保证,当锁被释放前,A看到的所有变量值(锁释放前,A看到的变量包括y和x)在B获得同一个锁后同样可以由B看到。换句话说,当线程B执行由锁保护的同步代码块时,可以看到线程A之前在同一个锁保护的同步代码块中的所有操作结果。如果在线程A unlock M之后,线程B才进入lock M,那么线程B都可以看到线程A unlock M之前的操作,可以得到i=1,j=1。如果在线程B unlock M之后,线程A才进入lock M,那么线程B就不一定能看到线程A中的操作,因此j的值就不一定是1。
现在考虑如下代码:
- public class MutableInteger
- {
- private int value;
- public int get(){
- return value;
- }
- public void set(int value){
- this.value = value;
- }
- }
以上代码中,get和set方法都在没有同步的情况下访问value。如果value被多个线程共享,假如某个线程调用了set,那么另一个正在调用get的线程可能会看到更新后的value值,也可能看不到。
通过对set和get方法进行同步,可以使MutableInteger成为一个线程安全的类,如下:
- public class SynchronizedInteger
- {
- private int value;
- public synchronized int get(){
- return value;
- }
- public synchronized void set(int value){
- this.value = value;
- }
- }
对set和get方法进行了同步,加上了同一把对象锁,这样get方法可以看到set方法中value值的变化,从而每次通过get方法取得的value的值都是最新的value值。
【Java并发编程】:内存可见性的更多相关文章
- Java并发编程-线程可见性&线程封闭&指令重排序
一.指令重排序 例子如下: public class Visibility1 { public static boolean ready; public static int number; } pu ...
- Java并发编程-volatile可见性的介绍
要学习好Java的多线程,就一定得对volatile关键字的作用机制了熟于胸.最近博主看了大量关于volatile的相关博客,对其有了一点初步的理解和认识,下面通过自己的话叙述整理一遍. 有什么用? ...
- Java并发编程:JMM(Java内存模型)和volatile
1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部 ...
- Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解
目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...
- Java并发编程(1)-Java内存模型
本文主要是学习Java内存模型的笔记以及加上自己的一些案例分享,如有错误之处请指出. 一 Java内存模型的基础 1.并发编程模型的两个问题 在并发编程中,需要了解并会处理这两个关键问题: 1.1.线 ...
- Java并发编程原理与实战四十二:锁与volatile的内存语义
锁与volatile的内存语义 1.锁的内存语义 2.volatile内存语义 3.synchronized内存语义 4.Lock与synchronized的区别 5.ReentrantLock源码实 ...
- 《java并发编程实战》读书笔记2--对象的共享,可见性,安全发布,线程封闭,不变性
这章的主要内容是:如何共享和发布对象,从而使它们能够安全地由多个线程同时访问. 内存的可见性 确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化. 上面的程序中NoVisibility可能 ...
- Java并发编程实战 02Java如何解决可见性和有序性问题
摘要 在上一篇文章当中,讲到了CPU缓存导致可见性.线程切换导致了原子性.编译优化导致了有序性问题.那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经 ...
- java并发编程实战《二》java内存模型
Java解决可见性和有序性问题:Java内存模型 什么是 Java 内存模型? Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为, Java 内存 ...
- Java并发编程里的volatile。Java内存模型核CPU内存架构的对应关系
CPU内存架构:https://www.jianshu.com/p/3d1eb589b48e Java内存模型:https://www.jianshu.com/p/27a9003c33f4 多线程下的 ...
随机推荐
- spring boot打包后windows启动乱码
事情的起因什么的就不多表了,直接进入主题... 项目都要上线了,结果发现使用 idea mvn install之后的 jar在windows下启动乱码,而使用idea启动却没有问题!!! 这是神马情况 ...
- Business Cards
Problem Description Running a paper shop is not an easy job, especially with harsh customers. Today ...
- hbase使用MapReduce操作4(实现将 HDFS 中的数据写入到 HBase 表中)
实现将 HDFS 中的数据写入到 HBase 表中 Runner类 package com.yjsj.hbase_mr2; import com.yjsj.hbase_mr2.ReadFruitFro ...
- ksplatform学习笔记
1.viewResolver配置中的: <bean id="viewResolver" class="org.springframework.web.servlet ...
- string 和String的区别
string 是 System.String 的别名,习惯上,我们把字符串当作对象时(有值的对象实体),我们用string.而我们把它当类时(需要字符串类中定义的方法),我们用String,比如: s ...
- [LeetCode 题解] Search in Rotated Sorted Array
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 题目描述 Suppose an array ...
- JavaScript從剪切板中獲取圖片並在光標處插入
edit_content_text.addEventListener('paste', function (ev) { var clipboardData, items, item; co ...
- [工具]JSON校验、转换在线工具
1. 在线JSON代码检验.检验.美化.格式化工具[简单易用的格式化工具]: http://tools.jb51.net/code/json 2. JSON在线格式化工具[代码高亮及可控缩进大小的格式 ...
- Unity的Shader如何控制投影颜色
细节慢慢补充,有几个需要注意的地方,必须要有接收投影的pass也就是Name是ShadowCollector的,必须添加#pragma multi_compile_fwdbase,物体的着色器必须有T ...
- TP5使用Composer安装phpoffice/phpspreadsheet,导出Excel文件
1.composer安装: composer require phpoffice/phpspreadsheet 2.点击导出按钮,触发控制器里面的方法 wdjzdc() 3. 在控制中引入 use P ...