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

Java并发之原子性、有序性、可见性及Happen Before原则

原子性

Java中的原子性是指一个操作或者多个操作,要么全部都执行并且执行的过程不会被任何因素中断,要么就全部都不执行。在Java中,原子性可以通过synchronizedLock关键字实现。除此之外,Java实现了java.util.concurrent.atomic包,提供了一系列原子性操作类,比如AtomicIntegerAtomicLong等等。这些原子性类中,常用的方法有:compareAndSetincrementAndGetdecrementAndGet等等。

有序性

Java中的有序性是指程序执行时,可能会对指令进行重排序,但是最终结果不变。在Java中,要保证有序性,可以使用volatile关键字,或者是synchronizedLock关键字。在使用volatile时,会保证读写操作的原子性和有序性。此外,Java中还有一种特别的有序性,称为程序顺序原则(POO,Program Order Rule),POO指的是在一个线程中,程序顺序规则保证了代码按照写在代码中的顺序依次执行。

可见性

Java中的可见性是指当一个线程修改了某个共享变量的值时,其他线程是否能够立即知道这个变量被修改的事实。在Java中,要保证可见性,可以使用volatile关键字,或者是synchronizedLock关键字。使用volatile关键字时,会强制线程每次都从主内存中读取变量的值,而不是从线程的本地缓存中读取。此外,Java中还有一种实现可见性的方法,就是使用synchronizedLock关键字。

Happen Before原则

Java中的Happen Before原则是指,在一定的情况下,任何一个操作事件的执行结果都能被后续的操作事件所看到。Java中有一些规则,可以确保满足Happen Before原则,包括:

  • 程序顺序原则(POO)
  • 传递性
  • volatile变量规则
  • 锁规则
  • 线程启动规则
  • 线程中断规则
  • 线程终结规则

其中,传递性规则表示:如果操作A Happen Before操作B,操作B Happen Before操作C,那么操作A Happen Before操作C。

示例说明

示例一

public class Example1 {
    private int count = 0;

    public synchronized void increase() {
        count++;
    }

    public static void main(String[] args) throws InterruptedException {
        final Example1 example = new Example1();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    example.increase();
                }
            }).start();
        }

        Thread.sleep(5000);
        System.out.println(example.count);
    }
}

上述代码创建了一个Example1类,该类中有一个成员变量count,和一个同步方法increase。通过创建10个线程,让它们同时访问increase方法,每次访问后将count自增1。由于synchronized关键字的保证,该程序将可以保证原子性和可见性。最终执行结果应该是:10000

示例二

public class Example2 {

    private volatile int value = 0;

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static void main(String[] args) throws InterruptedException {
        final Example2 example = new Example2();
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                example.setValue(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        while (example.getValue() == 0) {
            Thread.sleep(100);
        }

        System.out.println("value: " + example.getValue());
    }
}

上述代码创建了一个Example2类,其中有一个成员变量value,并且使用了volatile关键字进行修饰。在主线程中,创建了一个线程,并且在该线程中1秒后将value设置为1。在主线程中,通过while循环判断value是否为0。由于volatile关键字的保证,可以保证在判断value时,已经能获取到最新的value值,因此该程序将可以保证可见性。最终执行结果应该是:value: 1

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发之原子性 有序性 可见性及Happen Before原则 - Python技术站

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

相关文章

  • 举例解析Java多线程编程中需要注意的一些关键点

    下面是举例解析Java多线程编程中需要注意的一些关键点的攻略。 标题 Java多线程编程中需要注意的一些关键点 起因 Java多线程编程是Java程序员必备的技能之一,也是Java语言特有的特性。但是,由于多线程编程涉及到线程安全、锁机制、可见性等复杂问题,因此在编写多线程程序时,我们需要注意一些关键点,以避免出错、提高程序的性能和可靠性。 注意点 线程安全…

    多线程 2023年5月17日
    00
  • Python多线程多进程实例对比解析

    Python多线程多进程实例对比解析 本文将详细讲解Python中多线程与多进程的概念、区别、用法以及对比。 一、概念解析 1. 多线程 多线程是指在同一个程序中,多个线程可以并行执行,每个线程都可以独立运行,且每个线程也可以访问程序的内存,所以多线程编程能够实现很高的并发性。 2. 多进程 多进程是指在同一个操作系统中,多个进程可以并行执行,每个进程都可以…

    多线程 2023年5月17日
    00
  • 带你快速搞定java多线程

    带你快速搞定Java多线程 Java多线程是Java编程中非常重要的一个主题。多线程是指一个程序有多个线程同时进行,不仅可以提高程序的运行效率,还可以充分发挥多核CPU的优势。在本文中,我们将介绍Java多线程相关的基础知识和实践。 基本概念 线程:一个进程中的单个执行线程,它可以独立执行并拥有自己的状态、堆栈和局部变量 进程:正在运行的程序实例 并发:多个…

    多线程 2023年5月17日
    00
  • Java并发编程中使用Executors类创建和管理线程的用法

    一、介绍 在Java并发编程中,线程池是一种重要的技术。通过线程池执行任务可以大大减少资源的开销,提高程序的性能,避免线程过多导致系统资源耗尽的情况。而Executors类就是Java提供的一个专门用于创建和管理线程池的工具类。 二、使用步骤 创建线程池 创建线程池的方式有多种,其中Executors类提供了丰富的静态方法来创建不同类型的线程池。比较常用的是…

    多线程 2023年5月16日
    00
  • Python多线程threading join和守护线程setDeamon原理详解

    Python多线程threading join和守护线程setDeamon原理详解 简介 Python多线程是Python独特的功能之一,可以使程序在同一时间内执行多个并行任务。Python的线程模块提供了两个方法join()和setDaemon(),用于控制线程的行为。本文将详细介绍这两个方法的原理及使用方法。 join()方法 join()方法用于等待一…

    多线程 2023年5月17日
    00
  • Linux netstat命令查看并发连接数的方法

    当服务器负载过高或出现网络连接问题时,我们通常需要查看当前 TCP 连接数,进而找出问题的根源。在 Linux 环境下,netstat 是查看网络状态的绝佳工具。下面是查看并发连接数的方法: 命令 netstat -nat | awk ‘{print $6}’ | sort | uniq -c | sort -rn 命令参数说明 -n 表示不做 DNS 解析…

    多线程 2023年5月17日
    00
  • Go语言并发编程基础上下文概念详解

    Go语言并发编程基础上下文概念详解 并发编程是现代软件开发中非常重要的一部分,而Go语言则是一门专为并发编程而设计的语言。上下文(Context)概念则是Go语言并发编程中非常重要的一个概念。本文将详细讲解Go语言并发编程基础上下文概念。 什么是上下文? 上下文,英文叫做context,是Go语言标准库中的一个包,位于”context”目录下。上下文主要用来…

    多线程 2023年5月17日
    00
  • java虚拟机中多线程总结

    Java虚拟机中多线程总结 Java是一种支持多线程的编程语言,可以在同一个程序中同时运行多个线程。Java虚拟机(JVM)是Java程序的核心组件之一,多线程是JVM提供的一项非常重要的功能。在JVM中,多线程的实现方式主要有两种:基于进程的多线程和基于原生线程的多线程。 基于进程的多线程 基于进程的多线程是指在JVM内部使用单独的进程来实现多线程。这种多…

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