Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand Java multithreaded atomic operation classes

2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "how to understand Java multithreaded atomic operation class", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let Xiaobian take you to learn "how to understand Java multithreaded atomic operation class"!

directory

1、What and Why

2. Atomic update basic type class

3. Implementation principle

4. Atomic update array

5. Atomic update reference type

6. Atomic update field class

1、What and Why

Atoms are meant to be indivisible particles, and an operation is an atomic operation if it is an operation or a set of operations that cannot be interrupted. Obviously, atomic manipulation is safe because it cannot be interrupted.

Usually we see a lot of operations look atomic operations, but in fact are non-atomic operations, such as the very common i++ operation, which has value, plus one, write back and other operations behind it, if there are two threads to i plus one operation, it may result in i only become 2, this is thread unsafe update operation, of course we can use synchronized solution, but JUC provides java.util.concurrent.atomic package, The package's atomic manipulation classes provide a simple, efficient, thread-safe way to update a variable.

2. Atomic update basic type class

Updating the base types atomically, the Atomic package provides the following three classes:

AtomicBoolean: atomic update Boolean type

AtomicInteger: atomic update integer

AtomicLong: Atomic Update Long

The methods of the above three types are almost identical. Let's take AtomicInteger as an example to introduce the following methods.

int addAndGet(int data): atomically adds the input data to the original value of AtomicInteger and returns the result.

boolean compareAndSet(int expect, int update): If the input value is equal to the expected value expect, then update is assigned to the original value of AtomicInteger by atomic operation.

getAndIncrease (): atomically adds one to the original value of AtomicInteger, but note that this method returns the value before the increment.

int getAndSet(int newValue): Sets the original value of AtomicInteger to the value of newValue by atomic operation

void lazySet(int newValue): This will eventually be set to newValue, but using lazyset may cause other threads to read the old value a short time later.

class AtomicIntegerDemo{ static AtomicInteger atomicInteger = new AtomicInteger(0); public static void main(String[] args) { //Create a new thread pool ExecutorService threadPoolExecutor = new ThreadPoolExecutor(2, 4, 100, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); //Create a new thread threadPoolExecutor.execute( () -> { for (int i = 0; i

< 10; i++) { atomicInteger.incrementAndGet(); } }); //新建一个线程 threadPoolExecutor.execute(()->

{ for (int i = 0; i

< 10; i++) { atomicInteger.incrementAndGet(); } }); System.out.println(atomicInteger.get()); threadPoolExecutor.shutdown(); }}3、实现原理 public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; } 其中,unsafe类是Java用来处理一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,它使得Java拥有了类似C语言一样操作内存空间的能力。 valueOffset是字段value的内存偏移地址,valueOffset的值在AtomicInteger初始化时,在静态代码块中通过Unsafe的objectFieldOffset方法获取。在AtomicInteger中提供的线程安全方法中,通过字段valueOffset的值可以定位到AtomicInteger对象中value的内存地址,从而可以根据CAS实现对value字段的原子操作。 public final int getAndAddInt(Object o, long offset, int delta) { int v; do { v = getIntVolatile(o, offset); } while (!compareAndSwapInt(o, offset, v, v + delta)); return v; } 打开getAndAddInt()函数,可以看到这里使用了一个CAS机制的自旋锁来对v值进行赋值,关于CAS机制可以查看文章Java多线程 乐观锁和CAS机制 ,getIntVolatile方法用于获取对象o指定偏移量的int值,此操作具有volatile内存语义,也就是说,即使对象o指定offset的变量不是volatile的,次操作也会使用volatile语义,会强制从主存获取值,然后通过compareAndSwapInt来替换值,直到替换成功后,退出循环。 4、原子更新数组 使用原子的方式更新数组中的某个元素,Atomic包提供了以下3个类: AtomicReferenceArray:原子更新引用类型数组中的元素 AtomicIntegerArray:原子更新整型数组中的元素 AtomicLongArray:原子更新长整型数组中的元素 下面以AtomicIntegerArray为例介绍以下他们的方法: int addAndGet(int i, int delta):以原子的方式将输入值与数组中索引i的元素相加。 boolean compareAndSet(int i, int expect, int update):如果当前值等于预期值,则以原子方式将数组位置i的元素设置成update值 5、原子更新引用类型 刚刚提到的只能一次更新一个变量,如果要更新多个变量就需要使用原子更新引用类型提供的类了: AtomicReference:原子更新引用类型 AtomicReferenceFieldUpdater:原子更新引用类型里的字段 AtomicMarkableReference:原子更新带有标记位的引用类型。可以原子地更新一个布尔类型地标记位和引用类型。 AtomicReference 示例 class User{ private String name; public volatile int age; @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } public User(String name, int age) { this.name = name; this.age = age; }}class Reference{ static AtomicReference atomicUser = new AtomicReference(); public static void main(String[] args) { User u = new User("1",10); atomicUser.set(u); System.out.println(atomicUser.get()); atomicUser.compareAndSet(u,new User("2",15)); System.out.println(atomicUser.get()); System.out.println(atomicUser.compareAndSet(u, new User("3", 123))); System.out.println(atomicUser.compareAndSet(new User("2", 15), u)); }} AtomicReferenceFieldUpdate class AtomicFiled{ static AtomicReferenceFieldUpdater nameField = AtomicReferenceFieldUpdater.newUpdater(User.class,String.class,"name"); public static void main(String[] args) { // User u = new User("123",10); System.out.println(u); System.out.println(nameField.compareAndSet(u, "123", "xiaohua")); System.out.println(u); System.out.println(nameField.compareAndSet(u,"123","xiaoli")); }}

AtomicMarkableReference Example

The previous introduction is to modify a data under atomic operation. AtomicMarkableReference is different. It can not only be modified, but also defines a variable to determine whether it has been modified before. Here, we have to mention ABA problem:

The ABA problem is that if one thread changes the value of variable a from 1 to 2, and another thread changes the value of variable a from 2 back to 1, then the value of variable a is equivalent to not changing, but in fact has been changed. This is the ABA problem. A more vivid example can be given. There is a glass of water in the glass. Xiao Ming finishes it and then fills it with water and puts it back in place. At this time, Xiaohua comes. If he knows that the glass has been used, he will definitely not drink it again. If Xiao Ming records that the paper has been used after drinking, Xiaohua will know when he comes. AtomicMarkableReference provides such a Boolean variable to record whether the value has been modified.

AtomicMarkableReference initialization needs to pass a reference value (type is the generic filled in earlier), in addition to passing a Boolean value used to determine whether to modify. AtomicMarkableReference compareAndSet to pass two sets of parameters: old reference value and new reference value; old Boolean value and new Boolean value, only the old reference value and old Boolean value passed in the same value as the object, will modify the reference value and Boolean value.

class AtomicFiled{ static AtomicMarkableReference intMarkable = new AtomicMarkableReference(123,false); public static void main(String[] args) { System.out.println(intMarkable.getReference()); System.out.println(intMarkable.isMarked()); System.out.println(intMarkable.compareAndSet(123,100,false,true)); System.out.println(intMarkable.getReference()); System.out.println(intMarkable.isMarked()); System.out.println(intMarkable.compareAndSet(100,123,false,true)); }}6. Atomic update field class

If you need to update fields in a class atomically, you need to update the field class atomically. The Atomic package provides the following three classes:

AtomicIntegerFieldUpdater: atomically updates the updater of fields of integers

AtomicLongFieldUpdater: atomic updater for fields of long integers

AtomicStampedReference: atomically updates reference types with version numbers. Using version numbers to solve ABA problems

Note that atomically updating a field class requires two steps: the first step involves creating an updater with the static method newUpdate() and setting the class and properties you want to update. Second, fields (attributes) of the update class must use the public volatile modifier.

public class AtomicDemo { static AtomicReference atomicUsers = new AtomicReference(); static AtomicIntegerFieldUpdater userAge = AtomicIntegerFieldUpdater.newUpdater(User.class,"age"); static CountDownLatch countDownLatch = new CountDownLatch(2); public static void main(String[] args) throws InterruptedException { User u = new User("123",0); atomicUsers.set(u); ExecutorService threadPoolExecutor = new ThreadPoolExecutor(3, 6, 100, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(10), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); threadPoolExecutor.execute(()-> { try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" "+atomicUsers.get().getAge()); userAge.incrementAndGet(u); countDownLatch.countDown(); }); threadPoolExecutor.shutdown(); countDownLatch.await(); System.out.println(atomicUsers.get().getAge()); }} At this point, I believe that everyone has a deeper understanding of "how to understand Java multithreaded atomic operation classes," may wish to actually operate it! Here is the website, more related content can enter the relevant channels for inquiry, pay attention to us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report