Java並發編程原理與實戰十三:JDK提供的原子類原理與使用
阿新 • • 發佈:2018-08-02
執行 atomic .com new length 基本類 .get out sys
原子更新基本類型
原子更新數組
原子更新抽象類型
原子更新字段
原子更新基本類型:
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並發編程與實戰》龍果學院
Java並發編程原理與實戰十三:JDK提供的原子類原理與使用