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 see CAS from JUC source code

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

Share

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

This article mainly explains "how to look at CAS from JUC source code", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how to read CAS from JUC source code"!

1. What is CAS?

When it comes to CAS, we almost always think of optimistic lock, AtomicInteger, Unsafe.

Of course, it's possible that I didn't think of anything!

No matter what you think, my first impression is optimistic lock, after all, optimistic lock is often used to update transaction status, so I naturally think of this SQL:

Update trans_order set order_status = 1 where order_no = 'xxxxxxxxxxx' and order_status = 0

In fact, both set and where carry order_status.

Then what is CAS?

CAS is Compare-and-Swap, that is, compare and replace, which is commonly used in concurrent algorithms, and many classes use CAS under the JUC (java.util.concurrent) package.

A very common problem is the problem of multithreaded operation iSuppli +. The general solution is to add synchronized keyword modification. Of course, you can also use AtomicInteger code as an example:

Public class CasTest {private static final CountDownLatch LATCH = new CountDownLatch (10); private static int NUM_I = 0; private static volatile int NUM_J = 0; private static final AtomicInteger NUM_K = new AtomicInteger (0); public static void main (String [] args) throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool (10); for (int I = 0; I

< 10; i++) { threadPool.execute(new Runnable() { public void run() { for (int j = 0; j < 10000; j++) { NUM_I++; NUM_J++; NUM_K.incrementAndGet(); } LATCH.countDown(); } }); } LATCH.await(); System.out.println("NUM_I = " + NUM_I); System.out.println("NUM_J = " + NUM_J); System.out.println("NUM_K = " + NUM_K.get()); threadPool.shutdown(); } } 下面就从AtomicInteger开始了解CAS。 2.源码分析 public class AtomicInteger extends Number implements java.io.Serializable { private static final long serialVersionUID = 6214790243416807050L; // setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile int value; public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; } public final int decrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, -1) - 1; } } 可以看出里面使用了Unsafe类下的getAndAddInt方法,Unsafe类很多方法是本地(native)方法,主要是硬件级别的原子操作。 /** * @param var1 当前对象 * @param var2 当前对象在内存偏移量,Unsafe可以根据内存偏移地址获取数据 * @param var4 操作值 * @return */ public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { // 获取在var1在内存的值 var5 = this.getIntVolatile(var1, var2); // 将var1赋值为var5+var4, 赋值时会判断var1是否为var5 } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; } // 原子操作 public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5); 至于 compareAndSwapInt 的分析就忽略了。 看完代码过程其实就是: 比较var1的值是否为var4,是的话将var1更新为var5。 如果不是的话就一直循环,直到var1是var4。 3.问题总结 这要是一直获取不到,岂不是一直循环。线程多的情况下,会自旋很长时间,导致浪费资源。 你更新了, 我又给你更新回去了,你也不知道。ABA问题!比如像这样,A想更新值为a,还未抢到资源,这时候B进行了更新,将对象更新为了b,然后又马上更新回了a, 这时候A是什么都不知道的。 以乐观锁举例: -- 0 ->

1 update trans_order set order_status = 1 where order_no = 'xxxxxxxxxxx' and order_status = 0;-1-> 0 update trans_order set order_status = 1 where order_no =' xxxxxxxxxxx' and order_status = 0;-- 0-> 1 update trans_order set order_status = 1 where order_no = 'xxxxxxxxxxx' and order_status = 0

The solution can be to add version for version number control.

-- 0-> 1 update trans_order set order_status = 1 where order_no = 'xxxxxxxxxxx' and order_status = 0 and version = 0;-- 1-> 0 update trans_order set order_status = 1 where order_no =' xxxxxxxxxxx' and order_status = 0 and version = 1;-0-> 1 update trans_order set order_status = 1 where order_no = 'xxxxxxxxxxx' and order_status = 0 and version = 0

You can see the AtomicStampedReference class in the code:

/ * sets the value of the reference and the updated value given by the flag atomically, * if the current reference = = the expected reference, and the current flag = = expected flag. * * @ param expectedReference expects to reference the value updated by * @ param newReference * @ param expectedStamp expected flag * @ param newStamp updated flag * @ return {@ code true} if successful * / public boolean compareAndSet (V expectedReference, V newReference, int expectedStamp, int newStamp) {Pair current = pair Return expectedReference = = current.reference & & expectedStamp = = current.stamp & & ((newReference = = current.reference & & newStamp = = current.stamp) | | casPair (current, Pair.of (newReference, newStamp));}

In fact, it is to add an additional flag (stamp) to prevent ABA problems, similar to optimistic lock version.

At this point, I believe you have a deeper understanding of "how to look at CAS from the JUC source code". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow 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