墨风如雪博客

  • 源码小店
  • 导航站
  • 登录
  • java
  • 资源分享
让AI使用变得如此简单
  1. 首页
  2. java
  3. 正文

Java多线程的原子类

2023年 7月 8日 95点热度 0人点赞 0条评论

概述

什么是原子类

原子类是Java并发编程中的一种线程安全的变量类型,它能够保证对变量的操作是原子性的,即在并发环境下执行时能够保证操作的正确性和一致性。

原子类的作用

原子类的主要作用是实现多线程之间的数据共享和通信,保证多线程访问共享变量时的线程安全性,同时也能够提高程序的性能和效率。

原子类的分类

原子类主要分为以下几类:

  • AtomicInteger:对int类型的原子操作。
  • AtomicBoolean:对boolean类型的原子操作。
  • AtomicLong:对long类型的原子操作。
  • AtomicReference:对对象引用类型的原子操作。

Java中的原子类

AtomicInteger

AtomicInteger是Java原子类中的一种,它主要用于对int类型的变量进行原子操作。

AtomicInteger的基本操作

AtomicInteger提供了以下几种基本的操作方法:

  • get():获取当前的值。
  • set(int newValue):设置当前的值。
  • getAndSet(int newValue):先获取当前的值,然后设置为新的值。
  • compareAndSet(int expect, int update):如果当前值等于expect,则设置为update。

AtomicInteger的应用场景

AtomicInteger主要用于实现多线程之间的计数器,例如:

import java.util.concurrent.atomic.AtomicInteger;

public class Counter {

    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }
}

AtomicBoolean

AtomicBoolean是Java原子类中的一种,它主要用于对boolean类型的变量进行原子操作。

AtomicBoolean的基本操作

AtomicBoolean提供了以下几种基本的操作方法:

  • get():获取当前的值。
  • set(boolean newValue):设置当前的值。
  • getAndSet(boolean newValue):先获取当前的值,然后设置为新的值。
  • compareAndSet(boolean expect, boolean update):如果当前值等于expect,则设置为update。

AtomicBoolean的应用场景

AtomicBoolean主要用于实现多线程之间的状态标志,例如:

import java.util.concurrent.atomic.AtomicBoolean;

public class Task {

    private AtomicBoolean isRunning = new AtomicBoolean(false);

    public void start() {
        if (isRunning.compareAndSet(false, true)) {
            // 启动任务
        }
    }

    public void stop() {
        if (isRunning.compareAndSet(true, false)) {
            // 停止任务
        }
    }
}

AtomicLong

AtomicLong是Java原子类中的一种,它主要用于对long类型的变量进行原子操作。

AtomicLong的基本操作

AtomicLong提供了以下几种基本的操作方法:

  • get():获取当前的值。
  • set(long newValue):设置当前的值。
  • getAndSet(long newValue):先获取当前的值,然后设置为新的值。
  • compareAndSet(long expect, long update):如果当前值等于expect,则设置为update。

AtomicLong的应用场景

AtomicLong主要用于实现多线程之间的计数器,例如:

import java.util.concurrent.atomic.AtomicLong;

public class Counter {

    private AtomicLong count = new AtomicLong(0);

    public void increment() {
        count.incrementAndGet();
    }

    public long getCount() {
        return count.get();
    }
}

AtomicReference

AtomicReference是Java原子类中的一种,它主要用于对对象引用类型的变量进行原子操作。

AtomicReference的基本操作

AtomicReference提供了以下几种基本的操作方法:

  • get():获取当前的值。
  • set(Object newValue):设置当前的值。
  • getAndSet(Object newValue):先获取当前的值,然后设置为新的值。
  • compareAndSet(Object expect, Object update):如果当前值等于expect,则设置为update。

AtomicReference的应用场景

AtomicReference主要用于实现多线程之间的对象共享,例如:

import java.util.concurrent.atomic.AtomicReference;

public class Task {

    private AtomicReference<Result> result = new AtomicReference<>();

    public void setResult(Result newResult) {
        Result oldResult;
        do {
            oldResult = result.get();
        } while (!result.compareAndSet(oldResult, newResult));
    }

    public Result getResult() {
        return result.get();
    }
}

原子类与锁的比较

原子类的优点

原子类具有以下几个优点:

  • 线程安全:原子类能够保证对变量的操作是线程安全的,避免了多线程之间的竞争和冲突。
  • 性能高:原子类的实现采用了CAS算法,能够保证在多线程环境下的高效性能。
  • 简单易用:原子类的使用方法简单易懂,不需要加锁和解锁等复杂的操作。

原子类的缺点

原子类主要有以下两个缺点:

  • 只能保证单个变量的原子操作:原子类只能对单个变量进行原子操作,不能保证多个变量之间的操作的原子性。
  • 不能替代锁:在某些场景下,锁仍然是必需的,例如对于复杂的业务逻辑,原子类无法满足需求。

锁的优点

锁主要有以下几个优点:

  • 能够保证多个变量之间的原子操作:锁能够保证多个变量之间的操作的原子性,避免了数据的不一致性。
  • 能够实现复杂的业务逻辑:锁能够实现复杂的业务逻辑,例如对于需要对多个变量进行操作的场景。

锁的缺点

锁主要有以下两个缺点:

  • 性能低:在高并发的情况下,锁的性能会变得很低,导致程序的响应时间变长。
  • 容易出现死锁:如果锁的使用不当,容易出现死锁的情况,导致程序的崩溃。

原子类的实现原理

CAS(Compare and Swap)算法

原子类的实现主要采用了CAS算法。CAS算法是一种乐观锁的并发控制算法,它的核心思想是:先读取当前的值,然后比较当前值和期望值是否相等,如果相等,则更新为新的值,否则不更新。

ABA问题及解决方法

CAS算法存在一个问题,即ABA问题。ABA问题是指在并发环境下,如果一个值由A变为B,再由B变为A,那么CAS算法会误认为这个值没有被修改过。

为了解决ABA问题,Java原子类中的AtomicStampedReference类和AtomicMarkableReference类提供了一种解决方法,它们在原子操作时增加了一个版本号或标记位,用于检测对象是否被修改过。

Java中的实现方式

Java中的原子类主要是通过sun.misc.Unsafe类实现的,它提供了一些底层的操作方法,如:CAS、内存屏障等。原子类的实现方式主要包括以下几个步骤:

  1. 通过反射获取Unsafe对象。
  2. 使用Unsafe对象的方法来实现原子操作。

原子类的使用注意事项

线程安全性

虽然原子类能够保证对变量的操作是线程安全的,但是在使用时还是需要注意线程安全性问题。例如,多个线程同时对同一个原子类变量进行赋值操作时,可能会存在竞争和冲突,导致数据的不一致性。

原子类的可见性

原子类能够保证对变量的操作是原子性的,但是不能保证操作的可见性。如果一个线程对一个原子类变量进行修改,但是其他线程无法感知这个变化,就会导致数据的不一致性。为了解决这个问题,可以使用volatile关键字来保证原子类的可见性。

原子类的性能

原子类的性能相比于锁有所提高,但是在高并发的情况下,仍然会存在性能瓶颈。因此,在选择原子类或锁时,需要根据具体的业务场景进行权衡和选择。

总结

Java原子类是Java并发编程中的一种线程安全的变量类型,它能够保证对变量的操作是原子性的,并且具有高效性、简单易用等优点。Java中的原子类主要分为AtomicInteger、AtomicBoolean、AtomicLong和AtomicReference等几种,它们分别用于对int、boolean、long和对象引用类型的变量进行原子操作。在使用原子类时,需要注意线程安全性、可见性和性能等问题。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: java 原子性 原子类 多线程 并发 教程 线程池
最后更新:2023年 6月 11日

墨风如雪

一个热爱生活,热爱分享的程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

墨风如雪

一个热爱生活,热爱分享的程序员

最新 热点 随机
最新 热点 随机
告别机械感!OpenAudio S1让AI声音活起来 Sora触手可及!微软必应AI视频生成器,全民创作时代来临? 阿里WebAgent开源:引领自主搜索新纪元 重磅炸弹!字节跳动开源BAGEL:70亿参数,统一多模态理解与生成,AI“全能王”诞生记! 小米MiMo-VL:7B参数,怎么就成了多模态界的“越级打怪王”? 炸裂!DeepSeek 8B 量化版降临:告别显存焦虑,你的 3080 Ti 也能玩转顶级大模型了!
AI圈炸锅了!Mistral Medium 3:性能 SOTA,成本打骨折,企业玩家的新宠?字节终于开源“扣子”同款引擎了!FlowGram:AI 时代的可视化工作流利器告别“微信黑箱”!Chatlog:让你的聊天记录也能拥有“AI大脑”!字节跳动 Seed-Coder-8B:不靠人工洗数据,这80亿参数的小模型如何写出顶尖代码?85倍速的视觉革命:苹果发布 FastVLM,让你的 iPhone ‘看图说话’,快到飞起!告别AI视频“变脸怪”!腾讯混元Hunyuan Custom重磅开源,主体一致性“王炸”来了!
AI界的“变形金刚”:Transformer大模型趣味指南 Git 基础概念和命令详解 Java中Map集合的三种遍历方式 重塑AI推理格局?微软Phi-4模型震撼发布:轻量化性能炸裂 85倍速的视觉革命:苹果发布 FastVLM,让你的 iPhone ‘看图说话’,快到飞起! Linux知识点:Linux文件系统
标签聚合
设计模式 java AI 教程 算法 动态规划 spring deepseek

COPYRIGHT © 2023 墨风如雪博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

免责声明 - 隐私政策