并发编程的三大特性之原子性

简介: 并发编程的三大特性之原子性

原子性

这个定义是一种规定,描述了Java中的理想就是为了能实现一个操作不能分割,不可中断,一个线程在执行的时候,另一个线程不会去影响他。

Java中的原子性可以理解为多线程操作临界资源,预期的结果和最终的结果一致。

  • 原子性被破环的演示

如何保证并发编程中的原子性

  • 通过加锁的方式实现

CAS

CAS是compare and swap 是一条CPU级别的并发原语,CAS操作包括三个步骤:比较内存中的值、判断是否相等,如果相等则交换新值;如果不相等,则不做任何操作。这个操作是原子性的,即在执行过程中不会被其他线程中断。

  • 在Java中有使用基于Unsafe类提供关于CAS的操作方法。通过JVM帮助我们实现对CAS操作cpu的汇编指令。
  • CAS 需要注意的是他着重点 是比较和交换 ,值从哪里来需要我们自己获取
  • CAS的最主要应用就是实现乐观锁和锁自旋

CAS操作的时候只能使用对一个变量是原子性的,无法实现对多个

ABA问题:不符合原子操作

  • 解决方案:加入版本号

CAS锁自旋时间过长:

CAS基本都需要自旋,又遇上高并发就会陷入忙等待的状态,进程虽然繁忙但是无法前进

Lock锁

  • Lock是一个接口,我们使用的是他的一些实现类
  • 并发较多的情况下推荐使用ReentrantLock锁
public class Test10 {
    private static int count;
    /**
     * ReentrantLock 是一个对象,使用的时候要把他new出来
     */
    private static ReentrantLock lock = new ReentrantLock();

    public static void increment(){
        lock.lock();
        // 万一出错之后lock之后不会自动释放锁这一点和sy...不一样,需要在finally中释放锁资源
        try {
            count++;
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                increment();
            }
        });
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 100 ; i++) {
                increment();
            }
        });
        thread.start();
        thread2.start();
        thread.join();
        thread2.join();
        System.out.println(count);


    }
}

ReentrantLock可以直接对比synchronized,在功能上来说,都是锁。


但是ReentrantLock的功能性相比synchronized更丰富。


ReentrantLock底层是基于AQS实现的,有一个基于CAS维护的state变量来实现锁的操作。

ThredLocal

  • ThredLocal保证线程安全是不让多线程去操作临界资源
/**
 * @author 舒一笑
 * @date 2023/5/27
 */
public class Test11 {
    static ThreadLocal threadLocal1 = new ThreadLocal();
    static ThreadLocal threadLocal2 = new ThreadLocal();


    public static void main(String[] args) {
        threadLocal1.set("舒一笑");
        threadLocal2.set("每天写代码");
        Thread thread = new Thread(()->{
            System.out.println(threadLocal1.get());
            System.out.println(threadLocal2.get());
        });

        thread.start();

        System.out.println("主线程"+threadLocal1.get());
        System.out.println("主线程"+threadLocal2.get());
    }
}

  • 原理分析

  • 弱引用会被线程回收两头都会回收,key就没有了,所以在使用之后需要remove掉value防止内存泄露

  • 最后完整版应该加上这样两句话
目录
相关文章
|
7月前
|
缓存
并发编程的三大特性之可见性
并发编程的三大特性之可见性
33 0
|
Java 编译器 开发者
【并发编程的艺术】Java内存模型的顺序一致性
首先明确一点,顺序一致性内存模型是一个被理想化了的理论参考模型,提供了很强的内存可见性保证。其两大特性如下: 1)一个线程中的所有操作,必须按照程序的顺序来执行(代码编写顺序) 2)无论程序是否同步,所有线程都只能看到一个单一的操作执行顺序。每个操作都必须原子执行且立即对所有线程可见。
166 0
|
存储 缓存 SpringCloudAlibaba
JUC并发编程(一):Java内存模型(JMM)及三大特性:可见性、有序性、原子性
在当今高流量、高并发的互联网业务场景下,**并发编程技术**显得尤为重要,不管是哪一门编程语言,掌握并发编程技术是个人进阶的必经之路。时隔一个半月没有写技术博客文章,有点生疏了。。。闲话少叙,接下来我将围绕并发编程知识点进行总结讲解,这里从并发编程入门开始,讲述Java内存模型和并发的三大特性。
194 1
JUC并发编程(一):Java内存模型(JMM)及三大特性:可见性、有序性、原子性
|
7月前
|
缓存 安全 Java
多线程的三大特性:原子性、可见性和有序性
多线程的三大特性:原子性、可见性和有序性
149 0
|
7月前
|
安全 Java
并发编程的三大特性之有序性
并发编程的三大特性之有序性
32 0
|
7月前
|
Java 数据库
编程中的原子性(Atomicity)
编程中的原子性(Atomicity)
88 1
|
7月前
|
设计模式 并行计算 安全
【C/C++ 多线程编程】深入探讨双检锁与原子操作
【C/C++ 多线程编程】深入探讨双检锁与原子操作
230 0
|
安全 Java 数据库
【并发编程特性】并发编程特性之五种特性的探讨
【并发编程特性】并发编程特性之五种特性的探讨
93 0
|
缓存 安全 Java
Java并发编程三大特性
导致并发程序出现问题的根本原因
113 0
|
缓存 Java 编译器
并发编程(三)原子性&可见性&有序性
并发编程(三)原子性&可见性&有序性
122 0