墨风如雪博客

  • 源码小店
  • 传家宝VPS
让AI使用变得如此简单
  1. 首页
  2. java
  3. 正文

Java多线程的原子类

2023年 7月 8日 296点热度 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日

墨风如雪

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

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

文章评论

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

墨风如雪

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

最新 热点 随机
最新 热点 随机
Kimi K2.5开源:自带百人众包团队,月之暗面重新定义生产力 告别修图软件的图层噩梦,腾讯混元3.0让AI学会了“思考” 参数仅100亿却硬刚千亿巨头:阶跃星辰Step3-VL-10B凭什么封神? 腾讯CodeBuddy 2.0:从“副驾驶”到“全栈合伙人”的进化 97毫秒极致响应!Qwen3-TTS开源,重新定义语音生成的“速度与激情” 2026开年王炸:文心5.0带着2.4万亿参数和原生全模态来了
仅需1GB内存!腾讯混元MT1.5开源,让手机翻译彻底告别云端依赖十天谈下二十亿美金:Meta豪掷千金买下的中国AI天才,到底凭什么?智谱ZCode上手:把Claude和Gemini装进桌面,编程还能这么玩?告别延迟!通义开源Fun-Audio-Chat,这才是我们要的语音AI这可能是最懂人话的AI:阿里MAI-UI让手机自动驾驶成真DeepSeek新年炸场:给失控的AI模型装上数学红绿灯
告别AI塑料感:阿里Qwen3-Omni-Flash要把大模型做成真人 Mistral 掀桌了:Devstral 2 与 Vibe CLI 重塑开源编程体验 java IOC框架Spring Framework的(超详细总结) Kimi-Dev-72B:月之暗面如何用720亿参数“驯服”代码世界? 微信抛出亿元算力包,小程序AI变现的最后一块拼图补齐了 开源新王者DeepSeek-V3-0324:代码能力叫板Claude 3.7,MIT协议引爆AI普惠革命
标签聚合
大模型 设计模式 deepseek 教程 java 算法 spring AI

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

Theme Kratos Made By Seaton Jiang