项目中多次遇到了ABA的问题,对现有的解决方案都不太满意。最近在学习concurrent包中找到了一个解决方案。
package cas;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;
public class AtomicReferenceABATest {
//public final static AtomicReference <String>ATOMIC_REFERENCE = new AtomicReference<String>("abc");
public final static AtomicStampedReference <String>ATOMIC_REFERENCE = new AtomicStampedReference<String>("abc" , 0);//0就是当前的版本号
public final static CountDownLatch countDownLatch = new CountDownLatch(101);
public static void main(String []args) {
final int stamp = ATOMIC_REFERENCE.getStamp(); //获取版本号
for(int i = 0 ; i < 100 ; i++) {
final int num = i;
new Thread() {
public void run() {
System.out.println("线程:"+num+"准备修改数据");
if(ATOMIC_REFERENCE.compareAndSet("abc" , "abc2" , stamp , stamp + 1)) { //又api提供的cas控制函数来完成控制,非阻塞
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我是线程:" + num + ",我获得了锁进行了对象修改!"+ATOMIC_REFERENCE.getReference());
}
System.out.println("线程:"+num+"修改数据完成");
countDownLatch.countDown();
}
}.start();
}
new Thread() {
public void run() {
System.out.println("线程改回去:准备修改数据");
while(ATOMIC_REFERENCE.compareAndSet("abc2" , "abc" , stamp , stamp + 1));
System.out.println("已经改为原始值!");
countDownLatch.countDown();
}
}.start();
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ATOMIC_REFERENCE.getReference());
}
}
大牛的总结,mark一下http://www.blogjava.net/xylz/archive/2010/07/08/325587.html