1. 程式人生 > >Java並發編程原理與實戰十三:JDK提供的原子類原理與使用

Java並發編程原理與實戰十三:JDK提供的原子類原理與使用

執行 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提供的原子類原理與使用