日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第十一章 AtomicInteger源码解析

發布時間:2024/7/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第十一章 AtomicInteger源码解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、原子類

  • 可以實現一些原子操作
  • 基于CAS

下面就以AtomicInteger為例。

?

2、AtomicInteger

在沒有AtomicInteger之前,對于一個Integer的線程安全操作,是需要使用同步鎖來實現的,當然現在也可以通過ReentrantLock來實現,但是最好最方便的實現方式是采用AtomicInteger。

具體示例:

package com.collection.test;import java.util.concurrent.atomic.AtomicInteger;/*** 原子類的測試*/ public class AtomicTest {private static AtomicInteger atomicInteger = new AtomicInteger();//獲取當前值public static void getCurrentValue(){System.out.println(atomicInteger.get());//-->0 }//設置value值public static void setValue(){atomicInteger.set(12);//直接用12覆蓋舊值System.out.println(atomicInteger.get());//-->12 }//根據方法名稱getAndSet就知道先get,則最后返回的就是舊值,如果get在后,就是返回新值public static void getAndSet(){System.out.println(atomicInteger.getAndSet(15));//-->12 }public static void getAndIncrement(){System.out.println(atomicInteger.getAndIncrement());//-->15 }public static void getAndDecrement(){System.out.println(atomicInteger.getAndDecrement());//-->16 }public static void getAndAdd(){System.out.println(atomicInteger.getAndAdd(10));//-->15 }public static void incrementAndGet(){System.out.println(atomicInteger.incrementAndGet());//-->26 }public static void decrementAndGet(){System.out.println(atomicInteger.decrementAndGet());//-->25 }public static void addAndGet(){System.out.println(atomicInteger.addAndGet(20));//-->45 }public static void main(String[] args) {AtomicTest test = new AtomicTest();test.getCurrentValue();test.setValue();//返回舊值系列 test.getAndSet();test.getAndIncrement();test.getAndDecrement();test.getAndAdd();//返回新值系列 test.incrementAndGet();test.decrementAndGet();test.addAndGet();} } View Code

源代碼:

private volatile int value;// 初始化值/*** 創建一個AtomicInteger,初始值value為initialValue*/public AtomicInteger(int initialValue) {value = initialValue;}/*** 創建一個AtomicInteger,初始值value為0*/public AtomicInteger() {}/*** 返回value*/public final int get() {return value;}/*** 為value設值(基于value),而其他操作是基于舊值<--get()*/public final void set(int newValue) {value = newValue;}public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}/*** 基于CAS為舊值設定新值,采用無限循環,直到設置成功為止* * @return 返回舊值*/public final int getAndSet(int newValue) {for (;;) {int current = get();// 獲取當前值(舊值)if (compareAndSet(current, newValue))// CAS新值替代舊值return current;// 返回舊值 }}/*** 當前值+1,采用無限循環,直到+1成功為止* @return the previous value 返回舊值*/public final int getAndIncrement() {for (;;) {int current = get();//獲取當前值int next = current + 1;//當前值+1if (compareAndSet(current, next))//基于CAS賦值return current;}}/*** 當前值-1,采用無限循環,直到-1成功為止 * @return the previous value 返回舊值*/public final int getAndDecrement() {for (;;) {int current = get();int next = current - 1;if (compareAndSet(current, next))return current;}}/*** 當前值+delta,采用無限循環,直到+delta成功為止 * @return the previous value 返回舊值*/public final int getAndAdd(int delta) {for (;;) {int current = get();int next = current + delta;if (compareAndSet(current, next))return current;}}/*** 當前值+1, 采用無限循環,直到+1成功為止* @return the updated value 返回新值*/public final int incrementAndGet() {for (;;) {int current = get();int next = current + 1;if (compareAndSet(current, next))return next;//返回新值 }}/*** 當前值-1, 采用無限循環,直到-1成功為止 * @return the updated value 返回新值*/public final int decrementAndGet() {for (;;) {int current = get();int next = current - 1;if (compareAndSet(current, next))return next;//返回新值 }}/*** 當前值+delta,采用無限循環,直到+delta成功為止 * @return the updated value 返回新值*/public final int addAndGet(int delta) {for (;;) {int current = get();int next = current + delta;if (compareAndSet(current, next))return next;//返回新值 }}/*** 獲取當前值*/public int intValue() {return get();} View Code

說明:使用與源代碼都簡單到爆了!自己看看注釋。

注意:

  • value是volatile的,關于volatile的相關內容見《附2 volatile》,具體鏈接:http://www.cnblogs.com/java-zhao/p/5125698.html
  • 單步操作:例如set()是直接對value進行操作的,不需要CAS,因為單步操作就是原子操作。
  • 多步操作:例如getAndSet(int newValue)是兩步操作-->先獲取值,在設置值,所以需要原子化,這里采用CAS實現。
  • 對于方法是返回舊值還是新值,直接看方法是以get開頭(返回舊值)還是get結尾(返回新值)就好
  • CAS:比較CPU內存上的值是不是當前值current,如果是就換成新值update,如果不是,說明獲取值之后到設置值之前,該值已經被別人先一步設置過了,此時如果自己再設置值的話,需要在別人修改后的值的基礎上去操作,否則就會覆蓋別人的修改,所以這個時候會直接返回false,再進行無限循環,重新獲取當前值,然后再基于CAS進行加減操作。
  • 如果還是不懂CAS,類比數據庫的樂觀鎖

補充一個東西:

1 // setup to use Unsafe.compareAndSwapInt for updates 2 private static final Unsafe unsafe = Unsafe.getUnsafe(); 3 private static final long valueOffset; 4 5 static { 6 try { 7 valueOffset = unsafe.objectFieldOffset 8 (AtomicInteger.class.getDeclaredField("value")); 9 } catch (Exception ex) { throw new Error(ex); } 10 } 11 12 private volatile int value;

這是AtomicInteger的所有屬性,其中value存的是當前值,而當前值存放的內存地址可以通過valueOffset來確定。實際上是“value字段相對Java對象的起始地址的偏移量”

1 public final boolean compareAndSet(int expect, int update) { 2 return unsafe.compareAndSwapInt(this, valueOffset, expect, update); 3 }

CAS方法:通過對比“valueOffset上的value”與expect是否相同,來決定是否修改value值為update值。

轉載于:https://www.cnblogs.com/java-zhao/p/5140158.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的第十一章 AtomicInteger源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。