volatile

原子操作和volatile关键字

跟風遠走 提交于 2019-12-29 02:35:57
原子操作 :不可被中断的操作。要么全执行,要么全不执行。 现代CPU读取内存,通过读取缓存再写入主存。先去主存读--->写入缓存---->运行线程--->写入缓存---->写入主存 多cpu时会出现缓存一致性和总线锁的问题。 只有简单的读取,赋值操作,即一步完成的操作才是原子操作。 volatile,synchronized,lock 能保证可见性, volatile保证修改的值立即更新到主存,synchronized和lock保证同一时刻只有一个线程操作变量,在锁被释放前会将新值写入内存。 线程的有序性: java内存模型具备一些先天的有序性,即 happensbefore(先行发生)原则 : 1,程序次序规则,一个线程内,按照代码书写顺序执行 2,锁定规则,一个解锁操作ounlock先行发生于后面对同一个锁的lock操作 3,volatile变量规则,对一个变量的写操作先行发生于后面对这个变量的读操作 4,传递规则,A先发生于B,B先发生于C,则A先发生于C 5,线程启动规则,Thread对象的start()方法先行发生于此线程的每一个操作 6,线程中断规则,对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,即中断的发生先于中断被检测到 7,线程终结规则,线程中所有的操作都先行发生于线程的中止检测,可以通过Thread.join()方法结束

Java中锁的实现与内存语义

半世苍凉 提交于 2019-12-29 02:35:47
目录 1. 概述 2. 锁的内存语义 3. 锁内存语义的实现 4. 总结 1. 概述 锁在实际使用时只是明白锁限制了并发访问, 但是锁是如何实现并发访问的, 同学们可能不太清楚, 下面这篇文章就来揭开锁的神秘面纱. 2. 锁的内存语义 当线程获取锁时, JMM会把线程对应的本地内存置为无效. 从而使得被监视器保护的临界区的变量必须从主内存中读取. 当线程释放锁时, JMM会把该线程对应的本地内存中的共享变量刷新到主内存中(并不是不释放锁就不刷新到主内存, 只是释放锁时把未刷新到主内存中的数据刷新到主内存). 锁的内存语义与volatile的内存语义 锁获取与volatile读有相同的内存语义. 锁释放与volatile写有相同的内存语义. 内存语义总结 线程A释放一个锁, 实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共享变量所做修改的)消息. 线程B获取一个锁, 实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共享变量所做修改的)消息. 线程A释放锁, 随后线程B获取这个锁, 这个过程实质上是线程A通过主内存向线程B发送消息. 3. 锁内存语义的实现 下面以ReentrantLock为例, 获取到锁就是把state改为1(不考虑重入), 释放锁时改为0. 而加锁的关键代码就是 protected final boolean

为什么要用volatile

泄露秘密 提交于 2019-12-28 23:17:21
对于全局变量的访问,多线程同时访问,线程A和线程B可能只获得这个全局变量的一个备份(被弄到工作缓冲区了),这有可能导致线程A改变了全局变量的值,而线程B如果一直在忙,没有切换(比如执行sleep或synchronized),那么线程B里面要访问的全局变量就会一直 指向缓冲区里面的旧数据,除非线程B里面遇到sleep过synchronized这种语句让它有停顿过线程切换后再恢复回来这个线程才会刷新工作区,才会拿到全局变量的最新值。 除此以外,还可以在定义多线程访问又有机会被改变值的全局变量时,加上volatile关键字修饰,加了它就能保证此变量在各线程中保持全局可见。 来源: CSDN 作者: OK_boom 链接: https://blog.csdn.net/rocklee/article/details/103746950

Volatile and multithreading: is the following thread-safe?

时光毁灭记忆、已成空白 提交于 2019-12-28 16:33:10
问题 Assume there are two threads running Thread1() and Thread2() respectively. The thread 1 just sets a global flag to tell thread 2 to quit and thread 2 periodically checks if it should quit. volatile bool is_terminate = false; void Thread1() { is_terminate = true; } void Thread2() { while (!is_terminate) { // ... } } I want to ask if the above code is safe assuming that access to is_terminate is atomic. I already know many materials state that volatile can not insure thread-safety generally.

volatile关键字

无人久伴 提交于 2019-12-28 16:27:54
volitale关键字 简介:   volatile是Java提供的一种轻量级的同步机制。Java语言包含两种内在的同步机制:同步块(或方法)和volatile变量,相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。但是volatile变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错。 修饰的变量只能做赋值操作,不能做自增操作 1. 并发编程的3个基本概念 (1) 原子性 定义:即一个操作或者多个操作,要么全部执行并且执行过程不会被任何因素打断,要么就都不执行。 (2) 可见性 定义: 指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改的值 (3) 有序性 定义: 即线程执行的顺序按照代码的先后顺序执行 2. volatile关键字作用 保证内存可见性 private static volatile boolean flag = true; public static main(String[] args){ new Thread(()->{ try{ Thread.sleep(5000); } catch (InterruptedException){ e.printStackTrace(); } flag = false; })

Where to places fences/memory barriers to guarantee a fresh read/committed writes?

那年仲夏 提交于 2019-12-28 05:46:54
问题 Like many other people, I've always been confused by volatile reads/writes and fences. So now I'm trying to fully understand what these do. So, a volatile read is supposed to (1) exhibit acquire-semantics and (2) guarantee that the value read is fresh, i.e., it is not a cached value. Let's focus on (2). Now, I've read that, if you want to perform a volatile read, you should introduce an acquire fence (or a full fence) after the read, like this: int local = shared; Thread.MemoryBarrier(); How

May volatile be in user defined types to help writing thread-safe code

五迷三道 提交于 2019-12-28 05:01:06
问题 I know, it has been made quite clear in a couple of questions/answers before, that volatile is related to the visible state of the c++ memory model and not to multithreading. On the other hand, this article by Alexandrescu uses the volatile keyword not as a runtime feature but rather as a compile time check to force the compiler into failing to accept code that could be not thread safe. In the article the keyword is used more like a required_thread_safety tag than the actual intended use of

How to declare array elements volatile in Java?

旧时模样 提交于 2019-12-28 03:45:09
问题 Is there a way to declare array elements volatile in Java? I.e. volatile int[] a = new int[10]; declares the array reference volatile , but the array elements (e.g. a[1] ) are still not volatile. So I'm looking for something like volatile int[] a = new volatile int[10]; but it doesn't work that way. Is it possible at all? 回答1: Use AtomicIntegerArray or AtomicLongArray or AtomicReferenceArray The AtomicIntegerArray class implements an int array whose individual fields can be accessed with

Simplest and understandable example of volatile keyword in Java

会有一股神秘感。 提交于 2019-12-28 01:42:41
问题 I'm reading about volatile keyword in Java and completely understand the theory part of it. But, what I'm searching for is, a good case example, which shows what would happen if variable wasn't volatile and if it were. Below code snippet doesn't work as expected (taken from here): class Test extends Thread { boolean keepRunning = true; public void run() { while (keepRunning) { } System.out.println("Thread terminated."); } public static void main(String[] args) throws InterruptedException {

线程安全问题

淺唱寂寞╮ 提交于 2019-12-27 15:13:58
本篇主要讲解 线程安全问题,演示什么情况下会出现线程安全问题,以及介绍了 Java内存模型 、volatile关键字 、CAS 等 ,最后感谢吴恒同学的投稿! 一起来了解吧!!  1. 如何会发生线程安全  运行如下程序: /** * @program: * @description: 多线程操作的对象 * @author: * @create: **/ public class MyCount { private int myCount = 0 ; public int getMyCount() { return myCount; } public void setMyCount(int myCount) { this.myCount = myCount; } @Override public String toString() { return "MyCount{" + "myCount=" + myCount + '}'; } }  创建线程 public class CountThread1 extends Thread{ private MyCount myCount ; private static Object synch = new Object(); public CountThread1( MyCount myCount) { this.myCount =