AtomicLong 原子长整型

时间:2020-01-09 10:36:24  来源:igfitidea点击:

AtomicLong类为我们提供了一个long变量,该变量可以原子方式读取和写入,并且还包含高级原子操作,如compareAndSet()。 " AtomicLong"类位于" java.util.concurrent.atomic"包中,因此完整的类名为" java.util.concurrent.atomic.AtomicLong"。这段文字描述了Java 8中的AtomicLong版本,但第一个版本是在Java 5中添加的。

创建一个AtomicLong

创建一个" AtomicLong"是这样完成的:

AtomicLong atomicLong = new AtomicLong();

本示例创建一个初始值为0的AtomicLong。

如果要创建具有初始值的AtomicLong,可以这样进行:

AtomicLong atomicLong = new AtomicLong(123);

本示例将值123作为参数传递给AtomicLong构造函数,该构造函数将AtomicLong实例的初始值设置为123.

获得AtomicLong值

我们可以通过get()方法获取AtomicLong实例的值。这是一个" AtomicLong.get()"示例:

AtomicLong atomicLong = new AtomicLong(123);

long theValue = atomicLong.get();

设置AtomicLong值

我们可以通过set()方法设置AtomicLong实例的值。这是一个" AtomicLong.set()"示例:

AtomicLong atomicLong = new AtomicLong(123);

atomicLong.set(234);

本示例创建一个初始值为123的" AtomicLong"示例,然后在下一行将其值设置为" 234"。

比较并设置AtomicLong值

AtomicLong类也有一个原子的compareAndSet()方法。该方法将" AtomicLong"实例的当前值与期望值进行比较,如果两个值相等,则为" AtomicLong"实例设置一个新值。这是一个AtomicLong.compareAndSet()示例:

AtomicLong atomicLong = new AtomicLong(123);

long expectedValue = 123;
long newValue      = 234;
atomicLong.compareAndSet(expectedValue, newValue);

此示例首先创建一个初始值为123AtomicLong实例。然后,它将" AtomicLong"的值与期望值" 123"进行比较,如果它们相等,则" AtomicLong"的新值将变为" 234";

添加到AtomicLong值

AtomicLong类包含一些方法,可用于向AtomicLong添加值并返回其值。这些方法是:

  • addAndGet()
  • getAndAdd()
  • getAndIncrement()
  • incrementAndGet()

第一个方法addAndGet()将一个数字添加到AtomicLong中,并在添加后返回其值。第二种方法getAndAdd()也向AtomicLong添加了一个数字,但返回了AtomicLong在添加之前的值。我们应该使用这两种方法中的哪一种取决于用例。这是两个示例:

AtomicLong atomicLong = new AtomicLong();

System.out.println(atomicLong.getAndAdd(10));
System.out.println(atomicLong.addAndGet(10));

本示例将打印出值" 0"和" 20"。首先,该示例在将10加到之前获得" AtomicLong"的值。其加法前的值为0。然后,该示例将10加到AtomicLong中,并获得加法后的值。现在的值为20。

我们也可以通过这两种方法在AtomicLong中添加负数。结果实际上是相减。

" getAndIncrement()"和" incrementAndGet()"方法的工作方式与" getAndAdd()"和" addAndGet()"类似,只是将" AtomicLong"的值加1.

减去AtomicLong值

" AtomicLong"类还包含一些从原子上从" AtomicLong"值中减去值的方法。这些方法是:

  • decrementAndGet()
  • getAndDecrement()

" decrementAndGet()"从" AtomicLong"值中减去1,并在减去后返回其值。 getAndDecrement()也从AtomicLong值中减去1,但返回减法之前AtomicLong的值。

在Lambda表达式中使用AtomicLong作为计数器

Java Lambda表达式不能包含任何成员字段,因此在调用Lambda表达式之间它们不能在内部保留任何状态。但是,我们可以通过在Lambda表达式外部创建AtomicLong并从Lambda表达式内部使用它来绕过此限制。这是一个例子:

import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;

public class AtomicLongExample {

    public static void main(String[] args) {

        AtomicLong atomicLong = new AtomicLong();

        Function<Long, Long> myLambda = (input) -> {
            long noOfCalls = atomicLong.incrementAndGet();
            System.out.println("Lambda called " + noOfCalls + " times.");
            return input * 2;
        };

        System.out.println(myLambda.apply(1L));
        System.out.println(myLambda.apply(3L));
        System.out.println(myLambda.apply(5L));
    }
}

运行以上代码的输出如下所示:

Lambda called 1 times.
2
Lambda called 2 times.
6
Lambda called 3 times.
10