자바 병렬 프로 그래 밍 (14): 원자 변수 와 비 차단 동기 화 메커니즘
6337 단어 원자 변수 와 비 차단 동기 화 메커니즘
자물쇠 의 장점:
하드웨어 가 병발 에 미 치 는 영향:
비교 및 교환:
/**
* CAS
*/
public class SimulatedCAS {
private int value;
public synchronized int get(){
return value;
}
public synchronized int compareAndSwap(int expectedValue, int newValue){
int oldValue = value;
if (oldValue == expectedValue){
value = newValue;
}
return oldValue;
}
public synchronized boolean compareAndSet(int expectedValue, int newValue){
return (expectedValue == compareAndSwap(expectedValue, newValue));
}
}
차단 되 지 않 은 카운터:
/**
* CAS
*/
public class CasCounter {
private SimulatedCAS value;
public int getValue(){
return value.get();
}
public int increment(){
int v;
do {
v = value.get();
} while (v != value.compareAndSwap(v, v+1));
return v + 1;
}
}
JVM 의 CAS 지원:
원자 변수 클래스:
원자 변 수 는 '더 좋 은 volatile' 입 니 다.
/**
* CAS
*/
public class CasNumberRange {
private static class IntPair{
// : lower <= upper
final int lower;
final int upper;
public IntPair(int lower, int upper) {
this.lower = lower;
this.upper = upper;
}
}
private AtomicReference<IntPair> values = new AtomicReference<>();
public int getLower(){
return values.get().lower;
}
public int getUpper(){
return values.get().upper;
}
public void setLower(int i){
while (true){
IntPair oldv = values.get();
if (i > oldv.upper){
throw new IllegalArgumentException("lower can't > upper");
}
IntPair newv = new IntPair(i, oldv.upper);
if (values.compareAndSet(oldv, newv)){
return;
}
}
}
}
성능 비교: 자물쇠 와 원자 변수
/**
* ReentrantLock
*/
public class ReentrantLockPreudoRandom extends PseudoRandom{
private final Lock lock = new ReentrantLock(false);
private int seed;
public ReentrantLockPreudoRandom(int seed){
this.seed = seed;
}
public int nextInt(int n){
lock.lock();
try{
int s = seed;
seed = calculateNext(s);
int remainder = s % n;
return remainder > 0 ? remainder : remainder + n;
} finally{
lock.unlock();
}
}
...
}
/**
* AtomicInteger
*/
public class AtomicPseudoRandom extends PseudoRandom{
private AtomicInteger seed;
public AtomicPseudoRandom(int seed){
this.seed = new AtomicInteger(seed);
}
public int nextInt(int n){
while (true){
int s = seed.get();
int nextSeed = calculateNext(s);
if (seed.compareAndSet(s, nextSeed)){
int remainder = s % n;
return remainder > 0 ? remainder: remainder + n;
}
}
}
...
}
비 차단 알고리즘:
비 차단 스 택 구현:
/**
* Treiber
*/
public class ConcurrentStack<E> {
private AtomicReference<Node<E>> top = new AtomicReference<ConcurrentStack.Node<E>>();
public void push(E item){
Node<E> newHead = new Node<E>(item);
Node<E> oldHead;
do{
oldHead = top.get();
newHead.next = oldHead;
} while (!top.compareAndSet(oldHead, newHead));
}
public E pop(){
Node<E> oldHead;
Node<E> newHead;
do {
oldHead = top.get();
if (oldHead == null)
return null;
newHead = oldHead.next;
} while (!top.compareAndSet(oldHead, newHead));
return oldHead.item;
}
private static class Node<E>{
public final E item;
public Node<E> next;
public Node(E item){
this.item = item;
}
}
}
비 차단 링크 의 삽입 작업 실현:
/**
* , Michael-Scott
*/
public class LinkedQueue<E> {
private static class Node<E>{
final E item;
final AtomicReference<Node<E>> next;
public Node(E item, Node<E> next){
this.item = item;
this.next = new AtomicReference<>(next);
}
}
private final Node<E> dummy = new Node<E>(null, null);
private final AtomicReference<Node<E>> head =
new AtomicReference<>(dummy);
private final AtomicReference<Node<E>> tail =
new AtomicReference<>(dummy);
public boolean put(E item){
Node<E> newNode = new Node<E>(item, null);
while (true){
Node<E> curTail = tail.get();
Node<E> tailNext = curTail.next.get();
if (curTail == tail.get()){ //
if (tailNext != null){
// ( , ),
tail.compareAndSet(curTail, tailNext);
} else{
// ,
if (curTail.next.compareAndSet(null, newNode)){
// ,
tail.compareAndSet(curTail, tailNext);
return true;
}
}
}
}
}
}
원자의 도 메 인 업데이트 기:
private static class Node<E>{
private final E item;
private volatile Node<E> next; // volatile
public Node(E item){
this.item = item;
}
}
// CAS
private static AtomicReferenceFieldUpdater<Node, Node> nextUpdater
= AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "next");
ABA 문제:
아 낌 없 이 지적 하 다.