原子类型都位于java.util.concurrent.atomic包下,有如下类型(jdk8为例):
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerTest {
private static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) {
int numThreads = 10;
Thread[] threads = new Thread[numThreads];
// 创建并启动多个线程
for (int i = 0; i < numThreads; i++) {
threads[i] = new IncrementThread();
threads[i].start();
}
// 等待所有线程执行完毕
for (int i = 0; i < numThreads; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 输出最终的计数器值
System.out.println("Final counter value: " + counter.get());
}
static class IncrementThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
counter.incrementAndGet();
}
}
}
}
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayTest {
private static final int THREAD_COUNT = 10;
private static final int ARRAY_SIZE = 1000;
private static AtomicIntegerArray array = new AtomicIntegerArray(ARRAY_SIZE);
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[THREAD_COUNT];
// 创建并启动多个线程
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new IncrementThread();
threads[i].start();
}
// 等待所有线程执行完毕
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i].join();
}
// 打印数组中的元素
for (int i = 0; i < ARRAY_SIZE; i++) {
System.out.println("array[" + i + "] = " + array.get(i));
}
}
static class IncrementThread extends Thread {
@Override
public void run() {
for (int i = 0; i < ARRAY_SIZE; i++) {
array.incrementAndGet(i);
}
}
}
}
在上面的示例中,我们创建了一个长度为1000的AtomicIntegerArray对象,并创建了10个线程,每个线程都会对数组中的每个元素进行递增操作。
通过incrementAndGet()方法,我们可以原子地对数组中的元素进行递增操作,而无需使用synchronized关键字或volatile修饰符。
最后,我们打印数组中的元素,可以看到每个元素的值都被正确地递增了。这证明了AtomicIntegerArray的线程安全性。
下面是一个简单的示例,演示如何使用AtomicIntegerFieldUpdater来原子地更新一个类的int字段:
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AtomicIntegerFieldUpdaterTest {
private static class MyClass {
private volatile int value;
}
public static void main(String[] args) throws InterruptedException {
AtomicIntegerFieldUpdater updater = AtomicIntegerFieldUpdater.newUpdater(MyClass.class, "value");
MyClass myClass = new MyClass();
updater.set(myClass, 0);
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
updater.getAndIncrement(myClass);
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
updater.getAndDecrement(myClass);
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(updater.get(myClass)); // 输出: 0
}
}
在上面的示例中,我们创建了一个MyClass类,其中包含一个volatile修饰的value字段。然后,我们使用AtomicIntegerFieldUpdater创建了一个updater对象,用于原子地更新MyClass类的value字段。
接下来,我们创建了两个线程t1和t2,分别对value字段进行1000次递增和1000次递减操作。最后,我们等待两个线程执行完毕,并输出最终的value字段的值。
由于AtomicIntegerFieldUpdater提供了原子操作,所以最终输出的value字段的值应该是0。这是因为t1线程对value字段进行了1000次递增操作,而t2线程对value字段进行了1000次递减操作,两者相互抵消,所以最终值为0。
AtomicIntegerFieldUpdater和AtomicInteger都是Java并发包中的原子类,用于实现线程安全的操作。
主要的不同之处在于它们的使用场景和适用范围:
因此,AtomicIntegerFieldUpdater更加灵活,可以用于对任意类的字段进行原子操作,但是需要满足一定的条件。而AtomicInteger则更加简单直接,适用于对整型变量进行原子操作的场景。
另外,需要注意的是,由于AtomicIntegerFieldUpdater是通过反射来实现的,所以它的性能可能比AtomicInteger稍差一些。因此,在性能要求较高的场景下,可以优先考虑使用AtomicInteger。
页面更新:2024-02-28
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号