0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Java atomic中set()和lazySet()的区别

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-10-09 14:21 次阅读

在本教程中,我们将讲讲 Java atomic 类(如 AtomicIntegerAtomicReference )的方法 set()lazySet() 之间的区别。

原子变量

Java中的原子变量使我们能够轻松地对类的引用或字段进行线程安全的操作,而不需要添加监视器或互斥等并发原语。

它们被定义在 java.util.concurrent.atomic 包下,虽然它们的API根据原子类型的不同而不同,但大多数都支持set()lazySet()方法。

为了简单起见,我们将在本文中使用 AtomicReferenceAtomicInteger,但同样的原则适用于其他原子类型。

3.The set() 方法

在调用set()后,当我们从不同的线程使用get()方法访问该字段时,该变化是立即可见的。这意味着该值被从CPU缓存中刷新到了所有CPU核共有的内存层。为了展示上述功能,让我们创建一个最小的 producer-consumer 控制台应用。

public class Application {
    
        AtomicInteger atomic = new AtomicInteger(0);
    
        public static void main(String[] args) {
            Application app = new Application();
            new Thread(() - > {
                for (int i = 0; i < 10; i++) {
                    app.atomic.set(i);
                    System.out.println("Set: " + i);
                    Thread.sleep(100);
                }
            }).start();
    
            new Thread(() - > {
                for (int i = 0; i < 10; i++) {
                    synchronized (app.atomic) {
                        int counter = app.atomic.get();
                        System.out.println("Get: " + counter);
                    }
                    Thread.sleep(100);
                }
            }).start();
        }
    }

在控制台,我们应该看到一系列的 "设置 "和 "获取 "信息

Set: 3
    Set: 4
    Get: 4
    Get: 5

表明缓存一致性的是,"Get "语句中的值总是等于或大于其上方的 "Set "语句中的值。。

这种行为虽然非常有用,但也带来了性能上的影响。如果我们能在不需要缓存一致性的情况下避免它,那就太好了。

The lazySet() 方法

lazySet()方法与set()方法相同,但没有缓存刷新。

换句话说,我们的变化最终只对其他线程可见。这意味着从不同的线程对更新的 AtomicReference 调用 get()可能会给我们带来旧的值。

为了看到这一点,让我们在之前的控制台应用程序中改变第一个线程的Runnable

for (int i = 0; i < 10; i++) {
    app.atomic.lazySet(i);
    System.out.println("Set: " + i);
    Thread.sleep(100);
}

新的 "设置 "和 "获取 "信息可能不总是递增的。

Set: 4
Set: 5
Get: 4
Get: 5

由于线程的特性,我们可能需要重新运行几次应用程序,以便触发这种行为。尽管生产者线程已经将AtomicInteger设置为5,但消费者线程还是先检索到了值4,这意味着当lazySet()被使用时,系统最终是一致的。

在更多的技术术语中,我们说lazySet()方法在代码中不作为发生在前的边,与它们的set()对应的方法相反。

什么时候使用lazySet()

我们并不清楚什么时候应该使用lazySet(),因为它与set()的区别很微妙。我们需要仔细分析这个问题,不仅要确保我们会得到性能上的提升,还要确保在多线程环境下的正确性。

我们可以使用的一种方式是,一旦我们不再需要一个对象的引用,就用null替换它。这样,我们表明该对象有资格进行垃圾回收,而不会产生任何性能上的损失。我们假设其他线程可以使用废弃的值,直到他们看到AtomicReferencenull。不过一般来说,我们应该使用lazySet(),当我们想对一个原子变量进行修改,而且我们知道这个修改不需要立即对其他线程可见。

总结

在这篇文章中,我们看了原子类的set()lazySet()方法之间的区别。我们还学习了何时使用哪种方法。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    3024

    浏览量

    74038
  • JAVA
    +关注

    关注

    19

    文章

    2967

    浏览量

    104743
  • API
    API
    +关注

    关注

    2

    文章

    1499

    浏览量

    62001
  • SET
    SET
    +关注

    关注

    0

    文章

    17

    浏览量

    7951
  • 线程安全
    +关注

    关注

    0

    文章

    13

    浏览量

    2459
收藏 人收藏

    评论

    相关推荐

    JAVA和C++区别

    和c++的相似之处多于不同之处,但两种语言问几处主要的不同使得Java更容易学习,并且编程环境更为简单。 我在这里不能完全列出不同之处,仅列出比较显著的区别: 1.指针 JAVA语言让编程者无法找到
    发表于 04-11 15:19

    JAVA和C++区别

    和c++的相似之处多于不同之处,但两种语言问几处主要的不同使得Java更容易学习,并且编程环境更为简单。 我在这里不能完全列出不同之处,仅列出比较显著的区别: 1.指针 JAVA语言让编程者无法找到指针
    发表于 10-10 14:50

    Java和C++的区别

    和c++的相似之处多于不同之处,但两种语言问几处主要的不同使得Java更容易学习,并且编程环境更为简单。 我在这里不能完全列出不同之处,仅列出比较显著的区别: 1.指针 JAVA语言让编程者无法找到指针
    发表于 09-13 16:02

    this的使用场景及与C,Java的this的区别

    【JS】this有哪些使用场景?跟C,Java的this有什么区别?如何改变this的值?
    发表于 03-11 10:17

    Java SE、Java EE、Java ME之间的区别

    本文把JAVA SE、JAVA EE、JAVA ME拿来做下区别,同时也分享一下作者的一些成果。目前的Java平台根据软件开发人员、服务提供
    发表于 07-11 08:31

    JAVA SE、JAVA EE和JAVA ME有什么区别

    本文把JAVA SE、JAVA EE、JAVAME拿来做下区别,同时也分享一下作者的一些成果。目前的Java平台根据软件开发人员、服务提供商和设备生产商可以针对特定的市场可以分为三个版
    发表于 07-15 07:11

    Java基础概念

    1.什么是原子操作?在Java Concurrency API中有哪些原子类(atomic classes)?原子操作(atomic operation)意为"不可被中断的一个或一系列操作" 。
    发表于 08-02 06:00

    一文看懂scala和java区别

    本文开始对Scala的概念进行了详细说明,其次阐述了Java的定义以及Java的工作原理,最后阐述了scala和java区别以及scala相对于j
    的头像 发表于 03-07 18:30 6.5w次阅读
    一文看懂scala和<b class='flag-5'>java</b>的<b class='flag-5'>区别</b>

    java学习—null和isEmpty 区别

    本文档内容介绍了基于java学习null和isEmpty 区别,供参考
    发表于 03-13 10:26 0次下载

    python之集合set的基本步骤分享

    区别就是remove的元素在set当中没有的话会报错,而discard不会
    的头像 发表于 08-23 10:31 2171次阅读

    如何区分Javaprint和println

    在最开始学习Java的时候学到sout+enter键可以输出结果,显示的是System.out.println();而在Python是直接使用print。那么在Javaprint和
    的头像 发表于 02-21 15:10 1242次阅读

    javaweb和java有什么区别

    Javaweb和Java是两个不同的概念,它们之间存在明显的区别。下面将详细介绍这两者的区别,以满足你关于详尽、详实、细致的要求。 Java是一种广泛应用的编程语言和计算平台,它具有跨
    的头像 发表于 11-16 10:49 3581次阅读

    java的重载和重写的区别

    Java的重载(Overload)和重写(Override)是两个重要的面向对象编程概念,尽管它们在使用和功能上有所不同,但它们都与方法和多态性相关。本文将全面介绍重载和重写的概念、语法
    的头像 发表于 11-17 17:13 672次阅读

    pythonset类型

    Pythonset类型是一种无序、可变的集合数据类型,它的主要特点是不允许重复元素的存在。本文将详尽、详实、细致地介绍set类型的使用场景、常用操作以及与其他类型的比较等方面,以帮助读者全面了解
    的头像 发表于 11-21 16:25 894次阅读

    华纳云:java web和java有什么区别java web和java有什么区别

    Java Web和Java是两个不同的概念,它们在功能、用途和实现方式上存在一些区别,下面将详细介绍它们之间的区别。 1. 功能和用途: – Jav
    的头像 发表于 07-16 13:35 802次阅读
    华纳云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么<b class='flag-5'>区别</b><b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么<b class='flag-5'>区别</b>