Java并发之原子性,有序性,可见性,以及Happen-Before原则

原子性

原子性是指一个操作是不可中断的。即使是在多个线程一起执行的时候,操作一旦开始,也不会被其他线程干扰。即原子操作是一个做小操作。

例如 i++,其实经历了读,算,赋值绝对算不上是一个原子操作。一个i = 10这样的赋值操作可以称为原子操作。

java.util.comcurrent.atomic包里都是关于原子操作的类,有时间会另写一篇博客。

有序性

提到有序那必然就有乱序,而乱序是因为jvm的指令重排优化而产生的。

我们要想完全保住有序性,需要给对象加同步锁(synchronized),这样做实际上就是单线程执行了。

可见性

可见性是指当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道这个修改。

而其他线程看不到实际上是因为每个cpu都有寄存器,有一个线程把寄存器里的值修改了并提交到jvm了,而还有一个cpu的寄存器里存着数据的缓存,等它回头看jvm的时候,发现值已经变了。

Java提供了volatile关键字来保证可见性。

当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

下面用一段代码来做测试。

public class VisibilityTest extends Thread{  //如果没有关键字volatile,会发现这个线程停不掉,可自行测试。
    private volatile boolean stop;

    public void run() {
        int i = 0;
        while (!stop) {
            i++;
        }
        System.out.println("finish loop,i=" + i);
    }

    public void stopIt() {
        stop = true;
    }

    public boolean getStop() {
        return stop;
    }

    public static void main(String[] args) throws InterruptedException {
        VisibilityTest visibilityTest = new VisibilityTest();
        visibilityTest.start();
        visibilityTest.sleep(1000);
        visibilityTest.stopIt();
        System.out.println(visibilityTest.getStop());

    }
}

Happen-Before原则

? 程序顺序原则:一个线程内保证语义的串行性 a=1 b=a+1

? volatile规则:volatile变量的写,先发生于读,这保证了volatile变量的可见性

? 锁规则:解锁(unlock)必然发生在随后的加锁(lock)前

? 传递性:A先于B,B先于C,那么A必然先于C

? 线程的start()方法先于它的每一个动作 ? 线程的所有操作先于线程的终结(Thread.join())

? 线程的中断(interrupt())先于被中断线程的代码

? 对象的构造函数执行结束先于finalize()方法

原文地址:https://www.cnblogs.com/NoYone/p/8541898.html

时间: 2024-07-31 08:58:54

Java并发之原子性,有序性,可见性,以及Happen-Before原则的相关文章

深入理解Java虚拟机笔记---原子性、可见性、有序性

Java内存模型是围绕着并发过程中如何处理原子性.可见性.有序性这三个特征来建立的,下面是这三个特性的实现原理: 1.原子性(Atomicity) 由Java内存模型来直接保证的原子性变量操作包括read.load.use.assign.store和write六个,大致可以认为基础数据类型的访问和读写是具备原子性的.如果应用场景需要一个更大范围的原子性保证,Java内存模型还提供了lock和unlock操作来满足这种需求,尽管虚拟机未把lock与unlock操作直接开放给用户使用,但是却提供了更

并发之原子性、可见性、有序性

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用vola

Java自增原子性问题(测试Volatile、AtomicInteger)

这是美团一面面试官的一个问题,后来发现这是一道面试常见题,怪自己没有准备充分:i++;在多线程环境下是否存在问题?当时回答存在,接着问,那怎么解决?...好吧,我说加锁或者synchronized同步方法.接着问,那有没有更好的方法? 经过一番百度.谷歌,还可以用AtomicInteger这个类,这个类提供了自增.自减等方法(如i++或++i都可以实现),这些方法都是线程安全的. 一.补充概念 1.什么是线程安全性? <Java Concurrency in Practice>中有提到:当多个

并发编程之原子性、可见性、有序性的简单理解

并发程序正确地执行,必须要保证原子性.可见性以及有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 原子性:一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行. 可见性:当多个线程同时访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值. 有序性:程序执行的顺序按照代码的先后顺序执行. 对于单线程,在执行代码时jvm会进行指令重排序,处理器为了提高效率,可以对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证保

Java-JUC(二):volatile对Java内存模型中的可见性、原子性、有序性影响

Java内存模型 Java内存模型-可见性 Java内存模型-原子性 Java内存模型-有序性 volatile-是否具有可见性? volatile-是否具有原子性? volatile-是否具有有序性? 原文地址:https://www.cnblogs.com/yy3b2007com/p/8901518.html

java并发特性:原子性、可见性、有序性

要想并发程序正确地执行,必须要保证原子性.可见性以及有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并发的情况下,就不会出现变量被修改的情况 比如 a=0:(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作.再比如:a++: 这个操作实际是a = a + 1:是可分割的,所以

Java并发编程三个性质:原子性、可见性、有序性

并发编程 并发程序要正确地执行,必须要保证其具备原子性.可见性以及有序性:只要有一个没有被保证,就有可能会导致程序运行不正确 线程不安全在编译.测试甚至上线使用时,并不一定能发现,因为受到当时的CPU调度顺序,线程个数.指令重排的影响,偶然触发 线程安全的定义 比如说一个类,不论通过怎样的调度执行顺序,并且调用处不用对其进行同步操作,其都能表现出正确的行为,则这个类就是线程安全的 并发编程三个概念 原子性: 一个操作或多个操作要么全部执行且执行过程不被中断,要么不执行 可见性: 多个线程修改同一

2、原子性、可见性与有序性

原子性(Atomicity):由Java内存模型来直接保证的原子性变量操作包括read.load.assign.use.store和write,我们大致可以认为 基本类型的访问读写是具备原子性的. 如果应用场景还需要一个更大范围的原子性保证,Java内存模型还提供了lock和unlock操作来满足这种需求. 可见性(Visibility):可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改.Java内存模型是通过在变量修改后将 新值同步到主内存,无论是普通变量还是volatil

7.三大性质总结:原子性、可见性以及有序性

1. 三大性质简介 在并发编程中分析线程安全的问题时往往需要切入点,那就是两大核心:JMM抽象内存模型以及happens-before规则(在这篇文章中已经经过了),三条性质:原子性,有序性和可见性.关于synchronized和volatile已经讨论过了,就想着将并发编程中这两大神器在 原子性,有序性和可见性上做一个比较,当然这也是面试中的高频考点,值得注意. 2. 原子性 原子性是指一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着"同生共死"的感觉.及时在多个线程一起