java高并发的volatile与Java内存模型详解

Java内存模型和volatile

Java是一种并发语言,因此对于多线程并发的情况,必须要考虑更细致的问题。这些问题涉及到Java内存模型以及变量的可见性、有序性和原子性等等问题。其中,关于变量的可见性和原子性,Java中的volatile关键字有很重要的作用。

Java内存模型

Java内存模型(Java Memory Model,JMM)是一种抽象的规范,它定义了Java虚拟机如何和计算机内存进行交互。Java内存模型试图消除并发编程中存在的歧义和重排序问题。它定义了线程之间以及线程和主内存之间的数据传输和同步规则。

在Java内存模型中,共享变量存放在主内存中,而每个线程都有一份工作内存。工作内存是线程的私有数据区域,线程在执行操作时需要把变量从主内存拷贝到工作内存中。线程执行完操作后,将工作内存中的数据刷新回主内存。

volatile关键字

当多个线程访问同一个变量时,如果不进行同步操作,则会由于JVM的优化而导致线程之间的修改不可见。为了解决这个问题,Java SE 5引入了volatile变量,这个关键字保证了多线程之间修改变量时的可见性、有序性和原子性。

具体来说,当一个变量被声明为volatile变量时,读取这个变量和写入这个变量的操作都是对其它线程可见的。即使一个变量被同步机制保护,如果没有volatile修饰,其它线程仍然无法保证看到最新的值。

除了可见性外,volatile变量还保证了它们的操作是按照顺序执行的,即不会发生重排序。这对于一些需要顺序执行的操作非常重要,例如递增操作等等。

示例

示例1:不使用volatile关键字

public class Test {
    private static boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            flag = true;
            System.out.println("flag has changed to " + flag);
        }).start();

        while(!flag) {
            // do nothing
        }
        System.out.println("program end");
    }
}

在这个示例中,我们创建了两个线程。其中一个线程会1秒后将flag修改为true,而另一个线程会不断检查flag是否为true,并打印输出。但是,由于flag并没有使用volatile关键字进行修饰,因此另一个线程无法感知到flag的修改,最终程序将陷入死循环。

示例2:使用volatile关键字

public class Test {
    private static volatile boolean flag = false;
    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            flag = true;
            System.out.println("flag has changed to " + flag);
        }).start();

        while(!flag) {
            // do nothing
        }
        System.out.println("program end");
    }
}

在这个示例中,我们只需要在flag的定义前加上volatile关键字,就可以保证在另一个线程中感知到flag的修改。运行程序后,生产输出如下

flag has changed to true
program end

说明在另一个线程中成功地感知到了flag的修改。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java高并发的volatile与Java内存模型详解 - Python技术站

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

相关文章

  • Java并发线程池实例分析讲解

    Java并发线程池实例分析讲解 什么是线程池 线程池是一种用于管理多线程的机制,它可以维护一个线程队列,并在这些线程中动态地执行任务。线程池实现了资源的重复利用,在多线程应用中表现出色,可以提高系统的性能。 如何使用线程池 Java提供了一个Executor框架,用于从应用程序中的请求中分离出任务的执行和管理。Java.util.concurrent.Exe…

    多线程 2023年5月16日
    00
  • Java多线程(单例模式,阻塞队列,定时器,线程池)详解

    Java多线程详解 单例模式 单例模式可以确保在整个系统中只有一个实例化的对象。这在需要共享数据或资源的情况下非常有用。有多种方式可以实现单例模式,这里我们着重介绍两种方式:饿汉模式和懒汉模式。 饿汉模式 饿汉模式是一种线程安全的单例模式,也是最常见的单例模式之一。在类被加载时就创建了实例化对象,因此可以确保同时只有一个对象存在于内存中。 public cl…

    多线程 2023年5月17日
    00
  • C#多线程之线程池ThreadPool用法

    C#多线程之线程池ThreadPool用法 线程池ThreadPool是什么 在程序运行过程中,有时会出现需要进行并发处理的情况。与传统的线程操作(Thread类)相比,线程池可以更好地管理线程资源,提高线程的复用率,避免了频繁创建和销毁线程的开销,从而提高了程序的性能和稳定性。 线程池通过预先创建一组线程并维护这些线程,让它们在没有工作时处于等待状态,一旦…

    多线程 2023年5月16日
    00
  • Jmeter多台机器并发请求实现压力性能测试

    JMeter多台机器并发请求实现压力性能测试主要分为以下几个步骤: 1. 准备工作 确定测试目标:需要测试的页面或接口。 编写测试脚本:使用JMeter录制或手动编写HTTP请求脚本。 安装JMeter:在每台测试机器上安装JMeter。 配置JMeter:配置JMeter的相关设置,例如线程组、HTTP Cookie管理器等。 配置网络:将不同测试机器彼此…

    多线程 2023年5月16日
    00
  • JAVA多线程和并发基础面试问答(翻译)

    为了实现该攻略,首先我们需要明确一些关键点,如何理解多线程和并发,以及一些常见的面试问题和答案。 理解多线程和并发 在理解多线程和并发之前,先需要知道进程和线程的概念。 进程 在计算机科学中,进程是一个电脑程序运行时的实例。一个程序至少有一个进程。在操作系统中,进程是资源分配和调度的一个单位,每个进程都有其专用的地址空间、代码段、数据段和系统栈。 线程 线程…

    多线程 2023年5月16日
    00
  • Java并发编程之JUC并发核心AQS同步队列原理剖析

    针对“Java并发编程之JUC并发核心AQS同步队列原理剖析”的完整攻略,下面我将为您进行详细讲解,内容包含以下几个方面: JUC并发核心AQS AQS(AbstractQueuedSynchronizer)是JUC(JDK中对Java并发编程提供支持的工具包)并发编程的核心组件。AQS是一个用于构建锁和同步器的框架,利用AQS能够简单地构造出无锁、可重入、…

    多线程 2023年5月16日
    00
  • Java常见面试题之多线程和高并发详解

    Java常见面试题之多线程和高并发详解 简介 在Java的面试中,多线程和高并发是一个经常被问到的话题。因此,对于这个话题,我们必须掌握一些基本概念和技术来进行面试表现。 多线程和高并发的概念 多线程:在同一个程序中,多个线程能够共享同一个地址空间和文件描述符等类似的全局变量,允许并行运行多个线程。 高并发:指在同一时间内,有很多用户同时访问同一个资源,例如…

    多线程 2023年5月16日
    00
  • Java多线程 原子操作类详细

    Java多线程 原子操作类详细 什么是原子操作? 在计算机科学中,原子操作是指不可被进一步分割的操作。即使在并行的情况下执行,原子操作也会被看作是单个操作,不会被其他操作中断。在多线程编程中,对共享数据的修改必须是原子操作,否则就会出现竞态条件(Race Condition)的问题。 Java多线程中的原子操作 Java并发包中提供了一系列的原子操作类,包括…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部