【并發技術09】原子性操作類的使用
方法,其中包含:
1. 基本類型的使用
首先看一下 AtomicInteger 的使用,AtomicInteger 主要是針對整數的修改的,看一下示例代碼:
public class AtomicIntegerDemo {
public final static AtomicInteger TEST_INTEGER = new AtomicInteger(1);
public static void main(String []args) {
for(int i = 0 ; i < 10 ; i++) { //開啟10個線程
new Thread() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int now = TEST_INTEGER.incrementAndGet(); //自增
System.out.println(Thread.currentThread().getName() + " get value : " + now);
}
}.start();
}
來看一下結果:
Thread-3 get value : 4
Thread-7 get value : 5
Thread-9 get value : 9
Thread-4 get value : 6
Thread-0 get value : 3
Thread-1 get value : 8
Thread-5 get value : 11
Thread-8 get value : 7
Thread-2 get value : 10
Thread-6 get value : 2
可以看出,10 個線程之間是線程安全的,并沒有沖突。也就是說,我們使用原子性操作類去操作基本類型 int 就可以解決線程安全問題,一個線程在操作的時候,會對其它線程進行排斥,不用我們手動去使用 synchronized 實現互斥操作了。AtomicLong 和 AtomicBoolean 類似,就不舉例子了。
2. 數組類型的使用
下面要開始說 Atomic 的數組用法,Atomic 的數組要求不允許修改長度等,不像集合類那么豐富的操作,不過它可以讓數組上每個元素的操作絕對安全的,也就是它細化的力度還是到數組上的元素,做了二次包裝,雖然是數組類型的,但是最后還是操作數組中存的數,所以會了上面的基本類型的話,數組類型也很好理解。這里主要看一下 AtomicIntegerArray 的使用,其它的類似。
public class AtomicIntegerArrayTest {
private final static AtomicIntegerArray ATOMIC_INTEGER_ARRAY = new AtomicIntegerArray(new int[]{1,2,3,4,5,6,7,8,9,10});
public static void main(String []args) throws InterruptedException {
Thread []threads = new Thread[10];
for(int i = 0 ; i < 10 ; i++) {
final int index = i;
final int threadNum = i;
threads[i] = new Thread() {
public void run() {
int result = ATOMIC_INTEGER_ARRAY.addAndGet(index, index + 1);
System.out.println("線程編號為:" + threadNum + " , 對應的原始值為:" + (index + 1) + ",增加后的結果為:" + result);
}
};
threads[i].start();
}
for(Thread thread : threads) {
thread.join();
}
System.out.println("=========================>\n執行已經完成,結果列表:");
for(int i = 0 ; i < ATOMIC_INTEGER_ARRAY.length() ; i++) {
System.out.println(ATOMIC_INTEGER_ARRAY.get(i));
}
}
}
運行結果是給每個數組元素加上相同的值,它們之間互不影響。
3. 作為類屬性的使用
當某個數據類型是某個類中的一個屬性的時候,然后我們要操作該數據,就需要使用屬性原子修改器了,這里還是以 Integer 為例,即:AtomicIntegerFieldUpdater。示例代碼如下:
public class AtomicIntegerFieldUpdaterTest {
static class A {
volatile int intValue = 100;
}
public final static AtomicIntegerFieldUpdater ATOMIC_INTEGER_UPDATER = AtomicIntegerFieldUpdater.newUpdater(A.class, "intValue");
public static void main(String []args) {
final A a = new A();
for(int i = 0 ; i < 10 ; i++) {
new Thread() {
public void run() {
if(ATOMIC_INTEGER_UPDATER.compareAndSet(a, 100, 120)) {
System.out.println(Thread.currentThread().getName() + " 對對應的值做了修改!");
}
}
}.start();
}
}
}
可以看到,這里需要將類和類屬性傳進去才行,傳進去后其實跟前面操作 Integer 沒什么不同了,本質都一樣的,運行一下,結果只有一個線程能對其進行修改。
線程的原子性操作類的使用就簡單總結到這,其他的操作類原理都相似,可以參考 JDK 的文檔,可以很容易寫出相應的測試代碼。
來源:微信公眾號
任務調度 數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。