墨风如雪博客

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

Java多线程的原子类

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

墨风如雪

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

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

文章评论

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

墨风如雪

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

最新 热点 随机
最新 热点 随机
降维打击!Mistral Voxtral:开源语音的“终结者”已上线! AI“游侠”降临A股:16个“大脑”组团“炒股”,30秒“算命”市场! 视频魔法来了!AI能实时“变脸”直播,连游戏画面也能瞬间换装? 告别“听指令”,AI要“自己动手”了!ChatGPT Agent,AI界的“全能选手”已上线! 8B 模型吊打 671B?数学证明界“卷王”Goedel-Prover-V2 来了! Kiro来了!亚马逊放大招,软件开发要被AI“绑架”了吗?
昆仑万维扔出王炸:32B模型干翻671B,代码界迎来全能修理工!8亿参数撬动实时混音!谷歌开源“口袋DJ”,人人都能玩转音乐告别插件时代!OmniGen2:一个模型,通吃所有AIGC神操作2000万次呼唤背后,蓝骑士有了“赛博外挂”智能触手可及:Google Gemma-3n 系列模型,让万物皆能“思考”AI圈大地震!120亿参数的FLUX编辑器开源,你的显卡准备好了吗?
30亿参数逆袭!MonkeyOCR-3B如何革新文档解析? 告别抓耳挠腮!Gemini CLI,让你和你的终端聊上了天 Java CAS原理详解 告别繁琐,迎接智能:OpenAI Codex,你的专属AI编程伙伴来了! JVM使用进阶 调优与问题排查 风暴眼中的新王:阿里通义千问 Qwen2 登顶开源竞技场,Qwen2.5-Omni 或将掀起新浪潮?
标签聚合
教程 spring 设计模式 deepseek 算法 java AI 大模型

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

Theme Kratos Made By Seaton Jiang

免责声明 - 隐私政策