Java并发编程原理与实战十三:JDK提供的原子类原理与使用
原子更新基本类型
原子更新数组
原子更新抽象类型
原子更新字段
原子更新基本类型:
package com.roocon.thread.t8;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
public class Sequence {
private AtomicInteger value = new AtomicInteger(0);
private int [] s = {2,1,4,6};
AtomicIntegerArray a = new AtomicIntegerArray(s);
public int getNext(){
a.getAndIncrement(2);//给下标为2的元素加1
a.getAndAdd(2, 10);//获取下标为2的元素,并且加10
for (int i=0; i < a.length(); i++){
System.out.println(a.get(i));
}
return value.getAndIncrement();
}
public static void main(String[] args) {
Sequence sequence = new Sequence();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(Thread.currentThread().getName()+" "+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
运行结果:
Thread-0 0 Thread-1 1 Thread-2 2 Thread-0 3 Thread-1 4 Thread-2 5 ...
package com.roocon.thread.t8; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicIntegerArray; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.concurrent.atomic.AtomicReference; public class Sequence { private AtomicInteger value = new AtomicInteger(0); AtomicReference<User> user = new AtomicReference<>(); //对user的set和get执行原子操作 AtomicIntegerFieldUpdater<User> old = AtomicIntegerFieldUpdater.newUpdater(User.class, "old"); public int getNext(){ User user = new User(); System.out.println(old.getAndIncrement(user)); System.out.println(old.getAndIncrement(user)); System.out.println(old.getAndIncrement(user)); return value.getAndIncrement(); } public static void main(String[] args) { Sequence sequence = new Sequence(); new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+" "+sequence.getNext()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } }
运行结果:
0 1 2 Thread-0 0
对CAS的源码理解:--初步理解
在AtomicInteger中有这样一段源码:
public final int getAndUpdate(IntUnaryOperator updateFunction) { int prev, next; do { prev = get(); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(prev, next)); return prev; }
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
其中,compareAndSwap就是CAS的缩写。如果prev和next不相等,则返回true。否则,返回false。最终是通过unsafe来实现的。
以上代码表示,如果compareAndSet返回true,则while条件为false,退出循环,返回prev值。如果compareAndSet返回false,则while为true,继续执行循环体,重新获取prev的值,重新获取更新值,直到返回的compareAndSet值为true。
演示源码大致步骤如下:
Object prev = get(); //1 next = prev + 1; boolean flag = cas(prev, next); if (flag) { return prev; }else { go to 1 } Object pre
参考资料:
《java并发编程与实战》龙果学院