Java原子操作类AtomicInteger应用场景

Java中有那么一些类,是以Atomic开头的。这一系列的类我们称之为原子操作类。以最简单的类AtomicInteger为例。它相当于一个int变量,我们执行Int的 i++ 的时候并不是一个原子操作。而使用AtomicInteger的incrementAndGet却能保证原子操作。具体的类如下:

闲话不多说,还是用实例说话吧。

问题:现在有2个线程,分别将全局整型变量 i 进行加1。每个线程执行5000次。按照传统的int使用方式,代码如下:

private static int m = 0;

public static void main(String[] args) throws InterruptedException {
    CountDownLatch cdl = new CountDownLatch(2);

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int j = 0; j < 5000; j++) {
                m++;
            }
            cdl.countDown();
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int j = 0; j < 5000; j++) {
                m++;
            }
            cdl.countDown();
        }
    });
    t1.start();
    t2.start();

    cdl.await();
    System.out.println("result=" + m);
}

最后我们执行上面的代码,结果有可能是10000,但是大多数时候不是10000,而是随机的一些数字。这里的问题就在于 m++,如果我们在 m++的时候加上关键字synchronized也能解决该并发问题。但是synchronized过于沉重。于是我们可以考虑使用原子操作类AtomicInteger来实现。具体实现代码如下:

public static void main(String[] args) throws InterruptedException {
    CountDownLatch cdl = new CountDownLatch(2);
    AtomicInteger i = new AtomicInteger(0);

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int j = 0; j < 5000; j++) {
                i.incrementAndGet();
            }
            cdl.countDown();
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int j = 0; j < 5000; j++) {
                i.incrementAndGet();
            }
            cdl.countDown();
        }
    });
    t1.start();
    t2.start();

    cdl.await();
    System.out.println("result=" + i.get());
}

现在我们无论执行多少次,结果总是10000。

说明:

  1. m++并不是一个原子操作,而incrementAndGet却是原子操作方法

原文地址:https://www.cnblogs.com/duanjt/p/9717386.html

时间: 2024-08-27 18:30:51

Java原子操作类AtomicInteger应用场景的相关文章

java中的原子操作类AtomicInteger及其实现原理

/** * 一,AtomicInteger 是如何实现原子操作的呢? * * 我们先来看一下getAndIncrement的源代码: * public final int getAndIncrement() { * for (;;) { * int current = get(); // 取得AtomicInteger里存储的数值 * int next = current + 1; // 加1 * if (compareAndSet(current, next)) // 调用compareAnd

java原子操作类

java.util.concurrent.atomic包里面有原子操作相关的类 一.基本的类为 1.AtomicInteger 2.AtomicLong 3.AtomicBoolean 4.AtomicReference 5.AtomicStampedReference 6.AtomicMarkableReference 二.数组类为: 1.AtomicIntegerArray 2.AtomicLongArray 3.AtomicReferenceArray 三.类 1.AtomicIntege

【多线程与并发】Java中的12个原子操作类

从JDK1.5开始,Java提供了java.util.concurrent.atomic包,该包中的原子操作类提供了一种使用简单.性能高效(使用CAS操作,无需加锁).线程安全地更新一个变量的方式. `java.util.concurrent.atomic`包中的类.png 根据变量类型的不同,Atomic包中的这12个原子操作类可以分为4种类型: ①原子更新基本类型:AtomicBoolean.AtomicInteger.AtomicLong ②原子更新数组:AtomicIntegerArra

Java中的原子操作类

转载: <ava并发编程的艺术>第7章 当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2.因为A和B线程在更新变量i的时候拿到的i都是1,这就是线程不安全的更新操作,通常我们会使用synchronized来解决这个问题,synchronized会保证多线程不会同时更新变量i. 而Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以

第七章 Java中的13个原子操作类

当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i = 1:A线程更新i + 1,B线程也更新i + 1,经过两个线程操作之后可能i不等于3,而是等于2,.因为A和B线程在更新变量i的时候拿到的i都是1,这就是线程不安全的更新操作,通常我们会使用synchronized来解决这个问题,synchronized会保证多线程不会同时更新变量i. 而Java从JDK1.5开始提供了java.util.concurrent.atomic(以下简称Atomic包),这个包中

24.Java中atomic包中的原子操作类总结

1. 原子操作类介绍 在并发编程中很容易出现并发安全的问题,有一个很简单的例子就是多线程更新变量i=1,比如多个线程执行i++操作,就有可能获取不到正确的值,而这个问题,最常用的方法是通过Synchronized进行控制来达到线程安全的目的(关于synchronized可以看这篇文章).但是由于synchronized是采用的是悲观锁策略,并不是特别高效的一种解决方案.实际上,在J.U.C下的atomic包提供了一系列的操作简单,性能高效,并能保证线程安全的类去更新基本类型变量,数组元素,引用类

Java多线程之原子操作类

在并发编程中很容易出现并发安全问题,最简单的例子就是多线程更新变量i=1,多个线程执行i++操作,就有可能获取不到正确的值,而这个问题,最常用的方法是通过Synchronized进行控制来达到线程安全的目的.但是由于synchronized是采用的是悲观锁策略,并不是特别高效的一种解决方案.实际上,在J.U.C下的Atomic包提供了一系列的操作简单,性能高效,并能保证线程安全的类去更新多种类型.Atomic包下的这些类都是采用乐观锁策略CAS来更新数据. CAS原理与问题 CAS操作(又称为无

2.原子--深入浅出java原子操作

从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始).很多情况下我们只是需要一个简单的.高效的.线程安全的递增递减方案.注意,这里有三个条件:简单,意味着程序员尽可能少的操作底层或者实现起来要比较容易:高效意味着耗用资源要少,程序处理速度要快:线程安全也非常重要,这个在多线程下能保证数据的正确性.这三个条件看起来比较简单,但是实现起来却难以令人满意. 通常情况下,在Java里面,++

JDK的Atomic原子操作类实现机制

目录 通过JDK源码,品AtomicXXXFieldUpdater原子更新器及其优势 品Netty源码,学习原子更新的最佳实现方式 本篇文章大概3300字,阅读时间大约15分钟 如果仔细阅读过Netty的线程调度模型的源码,或者NIO线程对象及其线程池的创建源码,那么肯定会遇到类似“AtomicIntegerFieldUpdater”的身影,不禁想知道——Netty为何不直接使用原子类包装普通的比如计数的变量?下面带着这个疑问,深入Netty以及JDK源码去窥探一二,顺便学习先进的用法. 01