关于synchronized 影响可见性的问题】的更多相关文章

问题来自于学习thinking in java的时候的一个示例,先上代码吧 public class StopThread { private static boolean stop = false; public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new Runnable(){ public void run() { int i = 0; while (!sto…
之前的时候看<并发编程的艺术>,书中提到dcl写法的单例模式是有问题的,有可能会导致调用者得到一个创建了一半的对象,从而导致报错.修复办法是将单例对象的引用添加volatile进行修饰,禁用重排序,则外界获取的就一定是已经创建好的对象了. 光说总是不行的,上代码: public class SingleTest { private static SingleTest singleTest; // 这个应该用volatile修饰 //获取单例的方法 public static SingleTes…
问题: 大家可以先看看这个问题,看看这个是否有问题呢? 那里有问题呢? public class ThreadSafeCache { int result; public int getResult() { return result; } public synchronized void setResult(int result) { this.result = result; } } 如果你在这个问题上面停留超过5s的话,那么表示你对这块某些知识还有点模糊,需要再巩固下,下面我们一起来分析下…
在学习并发编程的时候,遇见了volatile和synchronized关键字问题,volatile是可以保证可见性,但无法保证原子性,synchronized关键字由于其是加锁机制,肯定是可以保证原子性的.但是它能保证可见性吗?也就是说被synchronized包裹的变量的值被修改后会立即送往主内存中吗?带着这个问题,我们继续往下看. 结论:volatile关键字只是用来修饰变量,并且保证变量的可见性:synchronized关键字只是用来修饰方法和代码块,并且保证里面的所有操作是原子性和可见性…
一.背景 最近在看<Java并发编程实战>这本书,看到共享变量的可见性,其中说到"加锁的含义不仅仅局限于互斥行为,还包括内存可见性". 我对于内存可见性第一反应是volatile:被volatile修饰的变量能够保证每个线程能够获取该变量的最新值,从而避免出现数据脏读的现象. 原因是volatile修饰的共享变量进行写操作的时候会多出Lock前缀的指令,通过多处理器的缓存一致性协议,来保持变量的同步更新. 但是我却没明白"加锁"与"可见性&qu…
JMM关于synchronized的两条规定: 1)线程解锁前,必须把共享变量的最新值刷新到主内存中 2)线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值 (注意:加锁与解锁需要是同一把锁) 通过以上两点,可以看到synchronized能够实现可见性.同时,由于synchronized具有同步锁,所以它也具有原子性 多线程中程序交错执行时,重排序可能会造成内存可见性问题 接下来我们看一段代码: /** * synchronized能够实现原子性(同步)…
以下是一个普通线程代码: package com.Sychronized; public class SychronizedDemo { //共享变量 private boolean ready=false; private int result=0; private int number=1; //写操作 public void write() { ready=true; //1.1 number=2; //1.2 } //读操作 public void read() { if(ready)…
变量不可见的两个原因 Java每个线程工作都有一个工作空间,需要的变量都是从主存中加载进来的.Java内存模型如下(JMM): 线程访问一个共享的变量时,都需要先从主存中加载一个副本到自己的工作内存中,经过自己修改后再更新到主存中去.在这个过程中可能出现这种情况:线程A在工作内存中修改了变量1的值,但是还没有写入主存,这档口线程B将变量1加载到自己工作内存中.显然,线程B拿到的不是变量1的最新值了. 变量可见性就是: 这个变量被任何一个线程修改了,其他线程都能“看见”,也就是能取到变量最新的值.…
Java内存的可见性 可见性: 一个线程对共享变量的修改,能够及时被其它线程看到 共享变量: 如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量 Java内存模型(JMM): 描述了Java程序中各种线程共享变量的访问规则,以及在JVM中将线程共享变量存储到内存和从内存中读取出线程共享变量这样的底层细节 上面这些规则都是针对线程的共享变量的,JMM的细节会在以后的博客里面写. 本篇只需要知道 1 所有的变量都存储在主内存中 2 每个线程都有自己独立的工作内存,里面…
编程这些实践的知识技能,每一次学习使用可能都会有新的认识 一.细说Java多线程之内存可见性(数据挣用)         1.共享变量在线程间的可见性                共享变量:如果一个变量在多个线程的工作内存中都存在副本,                         那么这个变量就是这几个线程的共享变量                可见性:一个线程对共享变量值的修改,能够及时的被其他线程看到                Java内存模型(JMM,Java Memory M…
1.Java HotSpot JVM运行时数据区 Java内存模型即Java Memory Model,简称JMM.JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式.JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的. 如果我们要想深入了解Java并发编程,就要先理解好Java内存模型.Java内存模型定义了多线程之间共享变量的可见性以及如何在需要的时候对共享变量进行同步.原始的Java内存模型效率并不是很理想,因此Java1.5版本对其进行了重构,现在的Java8仍…
目录 1. 关于synchronized关键字 2. synchronized的原理和实现细节 2.1 synchronized可以用在那些地方 2.2 synchronized是如何实现线程互斥访问的 2.3 对象锁的monitor信息存储在哪 2.4 monitor信息在对象头中的实现细节 3. synchronized的内存语义 3.1 synchronized的可见性分析 3.2 synchronized禁止指令重排吗 4.锁的优化 5. 总结 1. 关于synchronized关键字…
volatile关键字的2个作用 1.线程的可见性 2.防止指令重排 什么是线程的可见性? 线程的可见性 就是一个线程对一个变量进行更改操作 其他线程获取会获得最新的值. 线程在执行的行 操作主线程的变量.会将变量的副本拷贝一份到线程的工作区域(避免每次到主线程读取 提高效率),在更改后的一段时间内写入主内存 如下示例代码: public class Accounting implements Runnable { boolean quit=false; int i=0; @Override p…
参考文档: https://tech.meituan.com/java-memory-reordering.html http://0xffffff.org/2017/02/21/40-atomic-variable-mutex-and-memory-barrier/ 内存可见性:http://blog.csdn.net/ty_laurel/article/details/52403718 一.什么是重排序 重排序分为2种 编译期指令重排 通过调整代码中的指令顺序,在不改变代码语义的前提下,对变…
Volatile可见性 比如现在我们有这样一段代码:线程等待另一个线程将数据装载完就输出success,可是最后程序一直卡在while循环里没有往下执行. public class VolatileDemo { private static boolean flag = false; //private static volatile boolean flag = false; public static void main(String[] args) throws Exception{ ne…
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 感觉什么都不会,从哪开始呀! 这是最近我总能被问到的问题,也确实是.一个初入编程职场的新人,或是一个想重新努力学习的老司机,这也不会,那也不会,总会犯愁从哪开始. 讲道理,毕竟 Java 涉及的知识太多了,要学应该是学会学习的能力,而不是去背题.背答案,拾人牙慧是不会有太多收益的. 学习的过程要找对方法,遇到问题时最好能自己想想,你有哪些方式学会这些知识.是不感觉即使让你去百度搜,…
Java内存模型就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范. Java内存模型是根据英文Java Memory Model(JMM)翻译过来的.其实JMM并不像JVM内存结构一样是真实存在的.他只是一个抽象的概念.JSR-133: Java Memory Model and Thread Specifification中 描述了,JMM是和多线程相关的,他描述了一组规则或规范,这个规范定义了一个线程对共…
在前面的文章<双刃剑-理解多线程带来的安全问题>中,我们提到了多线程情况下存在的线程安全问题.本文将以这个问题为背景,介绍如何通过使用synchronized关键字解这一问题.当然,在青铜阶段,我们仍不会过多地描述其背后的原理,重点还是先体验并理解它的用法. 一.从场景中体验synchronized 是谁击败了主宰 在峡谷中,击败主宰可以获得高额的经济收益.因此,在条件允许的情况下,大家都会争相击败主宰.于是,哪吒和敌方的兰陵王开始争夺主宰.按规矩,谁是击败主宰的最后一击,谁便是胜利的一方.…
概述 我们都知道加锁的目的就是:序列化访问临界资源,即同一时刻只能有一个线程访问临界资源(同步互斥访问).在java对象中,每一个对象有且只有一个同步锁.这也意味着,同步锁依赖于对象而存在,当我们访问某对象的synchronized方法时,就获取了该对象的同步锁.synchronized的底层是使用操作系统的mutex lock实现的.先说明一下锁的一些相关概念. 锁的内存语义 内存可见性:同步快的可见性是由"如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前…
一.概述 1.synchronized作用 原子性:synchronized保证语句块内操作是原子的 可见性:synchronized保证可见性(通过"在执行unlock之前,必须先把此变量同步回主内存"实现) 有序性:synchronized保证有序性(通过"一个变量在同一时刻只允许一条线程对其进行lock操作") 2.synchronized的使用 修饰实例方法,对当前实例对象加锁 修饰静态方法,多当前类的Class对象加锁 修饰代码块,对synchronize…
想必在面试中经常会被问到Synchronized关键字,它有什么特性,原理什么 它的主要特性是同步锁.非公平锁.阻塞锁.可以保证线程安全(可见性.原子性.有序性) JDK1.6之后对Synchronized有优化,有个锁升级过程 Synchronized之保障线程安全 多线程情况下保障线程安全的方法有很多,一般都是通过加锁去竞争同一个资源,来达到互斥的效果,那么Synchronized是如何保障线程安全的呢 原子性 它的主要含义是要么全部成功要么全部失败,不允许部分成功部分失败,多线程中原子性是…
深入学习Synchronized各种使用方法 在Java当中synchronized通常是用来标记一个方法或者代码块.在Java当中被synchronized标记的代码或者方法在同一个时刻只能够有一个线程执行被synchronized修饰的方法或者代码块.因此被synchronized修饰的方法或者代码块不会出现数据竞争的情况,也就是说被synchronized修饰的代码块是并发安全的. Synchronized关键字 synchronized关键字通常使用在下面四个地方: synchroniz…
synchronized原理剖析 并发编程存在什么问题? 1️⃣ 可见性 可见性:是指当一个线程对共享变量进行了修改,那么另外的线程可以立即看到修改后的最新值. 案例演示:一个线程A根据 boolean 类型的标记 flag,while死循环:另一个线程B改变这个flag变量的值:那么线程A并不会停止循环. /** 案例演示: 一个线程对共享变量的修改,另一个线程不能立即得到最新值 */ public class Test01Visibility{ // 多个线程都会访问的数据,我们称为线程的共…
在<effective java>中看的的知识点,在工作中确实遇到了~ keywordsynchronized能够保证在同一时刻,仅仅有一个线程能够运行某一个方法,或者某一个代码块. 同步并非单单指线程之间的相互排斥. 假设没有同步,一个线程的变化就不能被其它线程看到. 同步不仅能够阻止一个线程看到对象处于不一致的状态之中, 它还能够保证进入同步方法或者同步代码块的每一个线程,都看到由同一个锁保护的之前的全部改动效果. 思考以下这个程序的执行过程是什么样的. import java.util.…
1. Java内存模型(Java Memory Model, JMM) Java的内存模型如下,所有变量都存储在主内存中,每个线程都有自己的工作内存. 共享变量:如果一个变量在多个线程中都使用到了,那么这个变量就是这几个线程的共享变量. 可见性:一个线程对共享变量的修改,能够及时地到主内存并且让其他的线程看到. 怎么理解上面的可见性的意思呢? 线程对共享变量的修改,只能在自己的工作内存里操作,不能直接对主内存中的共享变量进行修改.而且一个线程不能直接访问另一个线程中的变量的值,只能通过主内存进行…
Java内存模型JMM与可见性 标签(空格分隔): java 1 何为JMM JMM:通俗地讲,就是描述Java中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这样的底层细节. 结合上图,先介绍几个概念: 主内存:保存了所有的变量. 共享变量:如果一个变量被多个线程使用,那么这个变量会在每个线程的工作内存中保有一个副本,这种变量就是共享变量. 工作内存:每个线程都有自己的工作内存,线程独享,保存了线程用到了变量的副本(主内存共享变量的一份拷贝).工作内存负责…
从Java多线程:线程间通信之volatile与sychronized这篇文章中我们了解了synchronized的基本特性,知道了一旦有一个线程访问某个对象的synchronized修饰的方法或代码区域时,该线程则获取这个对象的锁,其他线程不能再调用该对象被synchronized影响的任何方法.那么,如果这个线程自己调用该对象的其他synchronized方法,Java是如何判定的?这就涉及到了Java中锁的重要特性:可重入性,也就是今天的主题. 1. 线程安全与可重入性 1.1. 线程安全…
synchronized和RetreenLock锁区别 1.synchronized是java关键字,RetreenLock是个java类 2.synchronized无法获取锁状态,Lock可以判断是否持有锁 3.synchronized会自动释放锁,Lock需要在finally中unlock()手动释放锁 4.使用synchronized,线程1获取锁,线程2只能等待:使用Lock,线程1获取锁,线程2会尝试获取锁,如果获取不到,不会一直等待,可以直接结束. 5.synchronized不可…
1. 三大性质简介 在并发编程中分析线程安全的问题时往往需要切入点,那就是两大核心:JMM抽象内存模型以及happens-before规则(在这篇文章中已经经过了),三条性质:原子性,有序性和可见性.关于synchronized和volatile已经讨论过了,就想着将并发编程中这两大神器在 原子性,有序性和可见性上做一个比较,当然这也是面试中的高频考点,值得注意. 2. 原子性 原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着“同生共死”的感觉.及时在多个线程一起执行的时候…
Java高并发--原子性可见性有序性 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 原子性:指一个操作不可中断,一个线程一旦开始,直到执行完成都不会被其他线程干扰.换句话说原子性保证了任何时刻只有一个线程在对共享变量进行操作. 可见性:指当一个线程修改了某个共享变量的值,其他线程是否能立即知道这个修改. 有序性:一个线程观察其他线程中的指令,由于指令重排序的存在,该观察结果一般杂乱无序 原子性 AtomicInteger JDK的atomic包下提供了许多"原子…