无风无影

   ::  :: 新随笔  ::  ::  :: 管理

AtomicStampedReference通过版本戳stamp解决ABA问题

  各种乐观锁的实现中通常都会用版本戳version来对记录或对象标记,避免并发操作带来的问题,在Java中,AtomicStampedReference<E>也实现了这个作用,它通过包装[E,Integer]的元组来对对象标记版本戳stamp,从而避免ABA问题,例如下面的代码分别用AtomicInteger和AtomicStampedReference来对初始值为100的原子整型变量进行更新,AtomicInteger会成功执行CAS操作,而加上版本戳的AtomicStampedReference对于ABA问题会执行CAS失败:

 1 import java.util.concurrent.TimeUnit;
 2 import java.util.concurrent.atomic.AtomicInteger;
 3 import java.util.concurrent.atomic.AtomicStampedReference;
 4 
 5 
 6 public class TestABA {
 7 
 8     private static AtomicInteger atomicInt = new AtomicInteger(100);
 9     private static AtomicStampedReference atomicStampedRef = new AtomicStampedReference(100, 0);
10 
11     public static void main(String[] args) throws InterruptedException {
12         Thread intT1 = new Thread(new Runnable() {
13             @Override
14             public void run() {
15                 atomicInt.compareAndSet(100, 101);
16                 atomicInt.compareAndSet(101, 100);
17             }
18         });
19 
20         Thread intT2 = new Thread(new Runnable() {
21             @Override
22             public void run() {
23                 try {
24                     TimeUnit.SECONDS.sleep(1);
25                 } catch (InterruptedException e) {
26                 }
27                 boolean c3 = atomicInt.compareAndSet(100, 101);
28                 System.out.println(c3); // true
29             }
30         });
31 
32         intT1.start();
33         intT2.start();
34         intT1.join();
35         intT2.join();
36 
37         Thread refT1 = new Thread(new Runnable() {
38             @Override
39             public void run() {
40                 try {
41                     TimeUnit.SECONDS.sleep(1);
42                 } catch (InterruptedException e) {
43                 }
44                 atomicStampedRef.compareAndSet(100, 101, atomicStampedRef.getStamp(), atomicStampedRef.getStamp() + 1);
45                 atomicStampedRef.compareAndSet(101, 100, atomicStampedRef.getStamp(), atomicStampedRef.getStamp() + 1);
46             }
47         });
48 
49         Thread refT2 = new Thread(new Runnable() {
50             @Override
51             public void run() {
52                 int stamp = atomicStampedRef.getStamp();
53                 try {
54                     TimeUnit.SECONDS.sleep(2);
55                 } catch (InterruptedException e) {
56                 }
57                 boolean c3 = atomicStampedRef.compareAndSet(100, 101, stamp, stamp + 1);
58                 System.out.println(c3); // false
59             }
60         });
61 
62         refT1.start();
63         refT2.start();
64     }
65 
66 }

 

posted on 2016-03-24 21:42  NWNS-无风无影  阅读(309)  评论(0)    收藏  举报