必须要学会的JMM与volatile

下面我为你详细讲解必须要学会的JMM与volatile的完整攻略。

JMM介绍

JMM(Java Memory Model)即Java内存模型,用于规范Java程序中线程对共享变量的操作。JMM为Java程序中的线程提供可见性、有序性、原子性等保证,从而提高程序并发性能。

JMM提供的保证

  • 可见性: 一个线程修改了共享变量的值,这个值的变化对其他线程是可见的。
  • 有序性: Java程序中的所有操作都是有序的,JMM通过禁止某些重排序优化来保证有序性。
  • 原子性: 对于某些复合操作,JMM保证这些操作要么全部执行,要么全部不执行。

JMM存在的问题

由于JVM的实现,每个线程都有自己的本地内存,线程之间的共享变量存于主内存中,因此在并发编程中需要考虑多线程之间的内存可见性和顺序性问题。

虽然JMM提供了可见性、顺序性、原子性的保证,但是只能保证某种程度的有序性和可见性,并不能保证所有的交互都按照开发人员预想的方式运行。

volatile关键字介绍

volatile关键字是JMM提供的一种保证内存可见性的手段。定义一个变量为volatile,JVM会避免执行重排序和缓存优化,保证该变量的每次写入都立即同步到主内存中,并且每次读取都从主内存中读取。

需要注意的是,volatile保证的是变量的可见性,保证的是单变量的操作是原子的,但是并不保证多次操作是原子的,因此对于多次操作的复合操作仍需使用锁或Atomic类进行保证。

volatile的用法

在Java中,声明一个变量为volatile需要使用volatile关键字来修饰:

public static volatile int count = 0;

在此例中,修饰的是静态变量count。该声明会告诉JVM将count存储到全局内存中,每个线程都将去电明这个全局变量,而且在修改count时会先更新到全局内存中。

下面是一个使用volatile关键字的示例:

public class VolatileTest {
    public static volatile int value = 0;

    public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                while (value == 0) {
                }
                System.out.println("Value has changed,value=" + value);
            }
        }.start();

        // main thread paused for 1s to make sure that the new thread already started
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        value = 1;
        System.out.println("Value is ready to change,value=" + value);
    }
}

在该示例中,启动了一个新线程,并在该线程内部对value进行了轮询,判断value是否被main线程修改,如果修改过则打印修改后的结果。在main线程中,修改了value的值为1,此时新线程会感知到value已经被修改并且会结束轮询并打印修改后的结果。

volatile与JMM的关系

JMM中提供了volatile关键字作为保证可见性的手段。volatile可以在一定程度上解决Java编程中的内存可见性问题。但是需要注意的是,volatile仅能保证单个变量的可见性,如果需要保证复合操作的原子性还需要使用synchronized或者Atomic类。

在Java并发编程中,虽然volatile不能保证一些复合操作的原子性,但是在一些特定的场景下使用volatile仍然是非常有用的,例如状态标志、单例模式等。

以上就是“必须要学会的JMM与volatile”的完整攻略了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:必须要学会的JMM与volatile - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 几道和「黑洞照片」那种海量数据有关的算法问题

    这个话题涉及到海量数据处理和算法问题,我会尽可能详细地解释来帮助大家了解。 大数据处理的常用算法 排序算法 排序是大数据处理中最常用的算法之一。这是因为,在许多情况下,我们需要对从数据库中获取的大量数据进行排序,以便更好地分析和使用它们。以下是一些常用的排序算法: 冒泡排序:这是一种简单的排序算法,在较小的数据集中表现良好,但对于大规模数据集则效率较低。 快…

    Java 2023年5月19日
    00
  • springboot学习之Thymeleaf模板引擎及原理介绍

    下面我会详细讲解“springboot学习之Thymeleaf模板引擎及原理介绍”的完整攻略。 一、Thymeleaf模板引擎的介绍 1.1 什么是Thymeleaf? Thymeleaf是一个流行的Java模板引擎,它允许开发人员使用自然模板语言在Web和非Web应用程序中构建HTML,XML,JavaScript,CSS和文本。它被广泛用于Spring …

    Java 2023年6月15日
    00
  • 深入了解Java中的Filter过滤器

    本文将深入讲解Java中的Filter过滤器。其中,我们会首先介绍Filter在Java Web开发中的应用场景和基本原理,之后我们会逐步讲解过滤器的使用方法和注意事项,最后以两个实例说明Filter的具体使用。让我们开始吧! 一、什么是Filter过滤器 在Java Web开发中,Servlet是最重要的组件之一,主要负责处理HTTP请求。但是,我们在开发…

    Java 2023年5月31日
    00
  • Spring Boot接口幂等插件用法示例解析

    Spring Boot接口幂等插件用法示例解析攻略 本文将详细介绍Spring Boot接口幂等插件的用法,并给出两个实例说明。 1. 简介 在分布式的应用中,为了保障数据的一致性,常常需要保证接口的幂等性。Spring Boot提供一个开源插件spring-boot-starter-idempotency来保证这一点。 该插件使用Redis来实现幂等性的检…

    Java 2023年5月26日
    00
  • jquery自定义下拉列表示例

    下面我来详细讲解一下“jQuery自定义下拉列表”的制作方法。 1. 简介 自定义下拉列表可以提升页面的交互体验,并且可以使页面更加美观。本文将使用jQuery来创建自定义下拉列表,包括如何使用HTML、CSS和JavaScript来实现。 2. 实现过程 下面我们以两个示例来详细讲解如何实现自定义下拉列表。 示例一 在这个示例中,我们将使用一个普通的&lt…

    Java 2023年5月19日
    00
  • java获取一个文本文件的编码(格式)信息

    获取一个文本文件的编码(格式)信息可以通过以下步骤进行: 读取文件的前几个字节,获取文件头信息。 根据文件头信息推测文件的编码格式。 具体操作如下: 读取文件头信息 try (InputStream inputStream = new FileInputStream(file)) { byte[] bytes = new byte[3]; inputStre…

    Java 2023年5月19日
    00
  • JUC中的wait与notify方法实现原理详解

    JUC中的wait与notify方法实现原理详解 JUC(Java Util Concurrent)是Java中用于处理多线程编程的库,其中包含了大量的线程处理类,其中常用的类之一是Object类中的wait方法和notify方法。本文将详细讲解JUC中的wait与notify方法实现原理。 wait方法的实现原理 wait方法是Object类中的一个方法,…

    Java 2023年5月26日
    00
  • 基于java中的流程控制语句总结(必看篇)

    基于Java中的流程控制语句总结(必看篇) 概述 在Java中,流程控制语句是指程序员可以通过使用一些关键字和语法来控制流程的执行顺序,使得程序能够根据不同的条件或者需求,动态控制流程的执行。Java中的流程控制语句包括分支语句和循环语句。 分支语句 Java中的分支语句主要有if-else和switch两种。 if-else语句 if-else语句是Jav…

    Java 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部