public class MyHolder {
private AtomicReference<Integer> value;
public MyHolder(AtomicReference<Integer> n) {
this.value = n;
}
/**
* @return the value
*/
public AtomicReference<Integer> getValue() {
return value;
}
/**
* @param value the value to set
*/
public void setValue(AtomicReference<Integer> value) {
this.value = value;
}
}
class MyRunnable implements Runnable {
private MyHolder obj;
public MyRunnable(MyHolder obj) {
this.obj = obj;
}
@Override
public void run() {
int i = 0;
while (i < 10) {
AtomicReference<Integer> counter = obj.getValue();
int current = counter.get();
System.out.println("before|current = " + current + "|" + Thread.currentThread().getName() + "竞争修改");
boolean flag = counter.compareAndSet(current, current + 1);
if (flag == false) {
System.out.println(Thread.currentThread().getName() + "更新失败, 期望的值= " + current + ", 但是现在的值="
+ counter.get());
} else {
System.out.println(Thread.currentThread().getName() + "成功更新, 期望的值 = " + current + ",期望更新后的值="
+ (++current) + ", 更新后现在的值=" + counter.get());
}
++i;
}
}
}
public class ConcurrentTestMain {
public static void main(String[] args) {
AtomicReference<Integer> atm = new AtomicReference<Integer>(1);
MyHolder myHolder = new MyHolder(atm);
Thread t1 = new Thread(new MyRunnable(myHolder));
Thread t2 = new Thread(new MyRunnable(myHolder));
Thread t3 = new Thread(new MyRunnable(myHolder));
Thread t4 = new Thread(new MyRunnable(myHolder));
t1.start();
t2.start();
t3.start();
t4.start();
}
}
部分整理后的日志如下:
before|current = 1|Thread-1竞争修改
before|current = 1|Thread-3竞争修改
before|current = 1|Thread-0竞争修改
before|current = 1|Thread-2竞争修改
Thread-0更新失败, 期望的值= 1, 但是现在的值=2
Thread-3更新失败, 期望的值= 1, 但是现在的值=2
Thread-1成功更新, 期望的值 = 1,期望更新后的值=2, 更新后现在的值=2
Thread-2更新失败, 期望的值= 1, 但是现在的值=2
before|current = 2|Thread-1竞争修改
before|current = 2|Thread-3竞争修改
before|current = 2|Thread-0竞争修改
Thread-1成功更新, 期望的值 = 2,期望更新后的值=3, 更新后现在的值=3
Thread-3更新失败, 期望的值= 2, 但是现在的值=4
Thread-0更新失败, 期望的值= 2, 但是现在的值=4
before|current = 3|Thread-1竞争修改
Thread-1成功更新, 期望的值 = 3,期望更新后的值=4, 更新后现在的值=4
before|current = 4|Thread-3竞争修改
before|current = 4|Thread-0竞争修改
before|current = 4|Thread-2竞争修改
before|current = 4|Thread-1竞争修改
Thread-0更新失败, 期望的值= 4, 但是现在的值=5
Thread-3成功更新, 期望的值 = 4,期望更新后的值=5, 更新后现在的值=5
Thread-2更新失败, 期望的值= 4, 但是现在的值=5
Thread-1更新失败, 期望的值= 4, 但是现在的值=5
before|current = 9|Thread-3竞争修改
before|current = 9|Thread-2竞争修改
before|current = 9|Thread-0竞争修改
Thread-3成功更新, 期望的值 = 9,期望更新后的值=10, 更新后现在的值=10
Thread-0更新失败, 期望的值= 9, 但是现在的值=17
Thread-2更新失败, 期望的值= 9, 但是现在的值=20
before|current = 5|Thread-3竞争修改
Thread-3成功更新, 期望的值 = 5,期望更新后的值=6, 更新后现在的值=6
before|current = 6|Thread-3竞争修改
before|current = 5|Thread-0竞争修改
Thread-0更新失败, 期望的值= 5, 但是现在的值=7
Thread-3成功更新, 期望的值 = 6,期望更新后的值=7, 更新后现在的值=7
before|current = 7|Thread-3竞争修改
before|current = 7|Thread-0竞争修改
before|current = 7|Thread-2竞争修改
Thread-0更新失败, 期望的值= 7, 但是现在的值=8
Thread-3成功更新, 期望的值 = 7,期望更新后的值=8, 更新后现在的值=8
before|current = 7|Thread-1竞争修改
before|current = 8|Thread-3竞争修改
before|current = 8|Thread-0竞争修改
Thread-2更新失败, 期望的值= 7, 但是现在的值=8
Thread-0更新失败, 期望的值= 8, 但是现在的值=9
Thread-3成功更新, 期望的值 = 8,期望更新后的值=9, 更新后现在的值=9
before|current = 10|Thread-3竞争修改
Thread-3成功更新, 期望的值 = 10,期望更新后的值=11, 更新后现在的值=11
before|current = 11|Thread-3竞争修改
Thread-3成功更新, 期望的值 = 11,期望更新后的值=12, 更新后现在的值=12
Thread-1更新失败, 期望的值= 7, 但是现在的值=8
before|current = 12|Thread-1竞争修改
Thread-1成功更新, 期望的值 = 12,期望更新后的值=13, 更新后现在的值=13
before|current = 13|Thread-1竞争修改
Thread-1成功更新, 期望的值 = 13,期望更新后的值=14, 更新后现在的值=14
before|current = 14|Thread-1竞争修改
Thread-1成功更新, 期望的值 = 14,期望更新后的值=15, 更新后现在的值=15
before|current = 15|Thread-1竞争修改
Thread-1成功更新, 期望的值 = 15,期望更新后的值=16, 更新后现在的值=16
before|current = 16|Thread-1竞争修改
Thread-1成功更新, 期望的值 = 16,期望更新后的值=17, 更新后现在的值=17
before|current = 17|Thread-0竞争修改
Thread-0成功更新, 期望的值 = 17,期望更新后的值=18, 更新后现在的值=18
before|current = 18|Thread-0竞争修改
Thread-0成功更新, 期望的值 = 18,期望更新后的值=19, 更新后现在的值=19
before|current = 19|Thread-0竞争修改
Thread-0成功更新, 期望的值 = 19,期望更新后的值=20, 更新后现在的值=20
before|current = 20|Thread-2竞争修改
Thread-2成功更新, 期望的值 = 20,期望更新后的值=21, 更新后现在的值=21
before|current = 21|Thread-2竞争修改
Thread-2成功更新, 期望的值 = 21,期望更新后的值=22, 更新后现在的值=22
before|current = 22|Thread-2竞争修改
Thread-2成功更新, 期望的值 = 22,期望更新后的值=23, 更新后现在的值=23
before|current = 23|Thread-2竞争修改
Thread-2成功更新, 期望的值 = 23,期望更新后的值=24, 更新后现在的值=24
before|current = 24|Thread-2竞争修改
Thread-2成功更新, 期望的值 = 24,期望更新后的值=25, 更新后现在的值=25
before|current = 25|Thread-2竞争修改
Thread-2成功更新, 期望的值 = 25,期望更新后的值=26, 更新后现在的值=26
结论:
可以看到,多个线程同时去修改,只有一个能正确修改,保证了线程安全。