首页 > 其他分享 >【多线程】原子类

【多线程】原子类

时间:2024-12-23 14:57:44浏览次数:4  
标签:引用 更新 原子 userRef user 多线程 User

JDK原子类基于CAS轻量级原子操作实现,使得程序运行效率变得更高。

(1)基本原子类
基本原子类的功能是通过原子方式更新Java基础类型变量的值。基本原子类主要包括以下三个:
 AtomicInteger:整型原子类。
 AtomicLong:长整型原子类。
 AtomicBoolean:布尔型原子类。


(2)数组原子类
数组原子类的功能是通过原子方式更新数组中的某个元素的值。数组原子类主要包括了以下
三个:
 AtomicIntegerArray:整型数组原子类。
 AtomicLongArray:长整型数组原子类。
 AtomicReferenceArray:引用类型数组原子类。


(3)引用原子类   保证对象引用的原子性
引用原子类主要包括以下三个:
 AtomicReference:引用类型原子类。
 AtomicMarkableReference:带有更新标记位的原子引用类型。
 AtomicStampedReference:带有更新版本号的原子引用类型。
AtomicMarkableReference类将boolean标记与引用关联起来,可以解决使用AtomicBoolean进行原子方式的更新时可能出现的ABA问题。
AtomicStampedReference类将整数值与引用关联起来,可以解决使用AtomicInteger进行原子方式的更新时可能出现的ABA问题。

引用原子类测试

public class User implements Serializable
{
    String uid; //用户ID
    String nickName; //昵称
    public volatile int age; //年龄
    public User(String uid, String nickName)
    {
        this.uid = uid;
        this.nickName = nickName;
    }    

测试代码:

public class AtomicTest
{
    @Test
    public void testAtomicReference()
    {
        //包装的原子对象
        AtomicReference<User> userRef = new AtomicReference<User>();
        //待包装的User对象
        User user = new User("1", "张三");
        //为原子对象设置值
        userRef.set(user);
        Print.tco("userRef is:" + userRef.get());
        //要使用CAS替换的User对象
        User updateUser = new User("2", "李四");
        //使用CAS替换
        boolean success = userRef.compareAndSet(user, updateUser);
        Print.tco(" cas result is:" + success);
        Print.tco(" after cas,userRef is:" + userRef.get());
    } 
}

首先创建了一个User对象,然后把User对象包装到一个AtomicReference类型的引用userRef中,如果要修改userRef的包装值,就需要调用compareAndSet()方法才能完成。该方法就是通过CAS操作userRef,从而保证操作的原子性。

使用原子引用类型AtomicReference包装了User对象之后,只能保障User引用的原子操作,对被包装的User对象的字段值修改时不能保证原子性,这点要切记。

 

(4)字段更新原子类:如果需要保障对象某个字段(或者属性)更新操作的原子性,需要用到属性更新原子类
字段更新原子类主要包括以下三个:
 AtomicIntegerFieldUpdater:原子更新整型字段的更新器。
 AtomicLongFieldUpdater:原子更新长整型字段的更新器。
 AtomicReferenceFieldUpdater:原子更新引用类型里的字段。

要求:

 第一步,更新的对象属性必须使用public volatile修饰符。
 第二步,因为对象的属性修改类型原子类都是抽象类,所以每次使用都必须使用静态方法newUpdater()创建一个更新器,并且需要设置想要更新的类和属性。

同时可以减少内存

 

字段更新原子类测试:继续基于上面的User类测试

public void testAtomicIntegerFieldUpdater()
{
    //使用静态方法newUpdater()创建一个更新器updater
    AtomicIntegerFieldUpdater<User> updater= AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
    User user = new User("1", "张三");
    //使用属性更新器的getAndIncrement、getAndAdd增加user的age值
    Print.tco(updater.getAndIncrement(user)); // 1
    Print.tco(updater.getAndAdd(user, 100)); // 101
    //使用属性更新器的get获取user的age值
    Print.tco(updater.get(user)); // 101
}

运行以上代码,结果如下:
[main]:0
[main]:1
[main]:101

实际应用

 

标签:引用,更新,原子,userRef,user,多线程,User
From: https://www.cnblogs.com/clarino/p/18624048

相关文章

  • 在.NET Core中使用异步多线程高效率的处理大量数据的一种解决方案
    目录一、引言二、假设场景三、解决方案四、示例代码一、引言处理大量数据是一个常见的需求,传统的同步处理方式往往效率低下,尤其是在数据量非常大的情况下。本篇将介绍一种高效的多线程异步处理大数据量的方法,通过边处理边消费的方式,极大地提高了处理效率,并且减少了内存开销。这......
  • 多线程-锁-写锁(独占锁)/读锁(共享锁)
    一个资源能够被多个读线程访问,或者被一个写线程访问,但是不能同时存在读写线程。特点        可重入        读写分离无锁无序→加锁→读写锁演变classMyResource{Map<String,String>map=newHashMap<>();//=====ReentrantLock等价于=====s......
  • python多线程爬取药品信息
    多线程爬取药品信息利用多线程来获取药品信息可以实现高效的爬取,方便我们自己对药品的名称、价格以及功效进行了解和掌握导入需要使用到的包fromconcurrent.futures.threadimportThreadPoolExecutorfromlxmlimportetreeimportrequestsimportrandomimportcsv......
  • 千峰教育--Netty 再学习 1 网络模型概述(BIO、NIO、AIO)、BIO 逻辑实现及其局限性(单线程
    课程介绍1网络模型概述2Channel详解3Buffer详解4Selector详解5NIO综合案例-聊天室6AIO概念及实现 1网络编程IO模型介绍1.1BLockingIOBlockingIO也称BIO,及同步阻塞IO。Java的io包基于流模型实现,提供了FIle,FileInputStream,FileOutputStream等输入输出流......
  • 【并发编程】第十一章 测试和调试多线程应用程序
    第十一章测试和调试多线程应用程序11.1与并发相关的bug类型有些类型的错误直接与并发的使用相关11.1.1不必要的阻塞线程因为等待某些条件(如互斥锁、条件变量、期值对象或I/O操作)而无法继续执行:死锁:两个或多个线程无限期地等待对方释放资源,导致程序挂起活锁:线程不断尝......
  • C++ 中的多线程编程:从基础到实战
        随着多核处理器的普及,多线程编程成为现代C++开发中的关键技能。C++11引入了强大的线程库,使得多线程编程更安全、更高效。本文将带你深入了解C++中的多线程编程,从基础概念到实际案例,逐步掌握如何用现代C++编写高效的多线程程序。一、多线程的基础概念  ......
  • linux-多线程
    目录​编辑一、线程  1.线程定义2.线程的优点:3.线程的缺点4.线程异常:5.线程用途:6.Linux进程VS线程     linux线程控制        创建线程:线程终止:线程等待 分离线程Linux线程互斥互斥量mutex互斥量的接口初始化互斥量销毁互斥量阻塞......
  • 【Java学习笔记】多线程基础
    并行:同一时刻,多任务同时进行多任务分别进行一、线程相关概念1.程序是为完成特定任务、用某种语言编写的一组指令的集合。简单的说:就是我们写的代码2.进程(1)进程指的就是运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存空间。当我们使用迅......
  • Java多线程
    多线程总结Java中的多线程是Java编程语言中的一个重要特性,它允许多个线程同时执行,从而提高程序的性能和响应能力。多线程在处理并发任务、优化资源利用率以及构建高性能应用程序方面发挥着关键作用。本文将详细介绍Java中的多线程,包括其基本概念、线程的创建与管理、线程同步、并......
  • Java多线程第一篇-认识多线程
    文章目录进程和线程概念继承Thread重写run方法实现Runnable重写run方法(解耦合)通过匿名内部类lambda表达式线程的常见的属性(方法)Id(getId)名称(getName)是否后台线程(isDaemon)是否存活(isAlive)进程和线程概念进程(process):进程是操作系统资源分配的基本单位,操作系统......