欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中的AtomicLong原理、使用與實(shí)戰(zhàn)指南

 更新時間:2025年03月05日 10:23:01   作者:jiet_h  
本文詳細(xì)介紹了AtomicLong在Android多線程開發(fā)中的應(yīng)用,包括其核心原理、基本使用、適用場景、生產(chǎn)環(huán)境實(shí)戰(zhàn)案例以及性能優(yōu)化建議,通過大量Kotlin代碼示例,幫助開發(fā)者更好地理解和使用AtomicLong,感興趣的朋友一起看看吧

本文結(jié)合生產(chǎn)環(huán)境實(shí)戰(zhàn)案例,帶你徹底搞懂AtomicLong在Android多線程開發(fā)中的應(yīng)用。全文包含大量Kotlin代碼示例,建議收藏備用。

一、為什么需要AtomicLong?

在Android開發(fā)中,當(dāng)多個線程同時操作同一個Long型變量時,你可能會遇到這樣的詭異場景:

var counter = 0L
fun increment() {
    // 這個操作在并發(fā)場景下會出錯!
    counter++ 
}

這個簡單的自增操作,編譯后會變成多條JVM指令(ILOAD, LCONST_1, LADD, LSTORE),根本不是原子操作!普通Long變量在多線程環(huán)境下存在安全隱患。

二、AtomicLong的核心原理

2.1 CAS機(jī)制

AtomicLong底層采用CAS(Compare And Swap)算法:

// 偽代碼實(shí)現(xiàn)
fun incrementAndGet(): Long {
    while(true) {
        val current = get()
        val next = current + 1
        if (compareAndSet(current, next)) {
            return next
        }
    }
}

這個過程就像超市寄存柜——只有當(dāng)柜子里的物品和預(yù)期一致時,才能放入新物品。通過自旋重試機(jī)制保證原子性,但要注意CPU資源消耗。

2.2 內(nèi)存可見性

通過volatile關(guān)鍵字保證修改的可見性:

// JDK源碼片段
private volatile long value;
public final long get() {
    return value;
}

這個設(shè)計(jì)讓所有線程都能立即看到最新值。

三、AtomicLong的基本使用

3.1 初始化方式

// 初始值為0
val atomicCounter = AtomicLong()
// 帶初始值
val pageViewCounter = AtomicLong(1000)

3.2 常用方法詳解

方法名等價操作說明
get()val = x獲取當(dāng)前值
set(newValue)x = new直接賦值(慎用!)
getAndIncrement()x++先返回舊值再+1(適合計(jì)數(shù)統(tǒng)計(jì))
incrementAndGet()++x先+1再返回新值
compareAndSet(expect, update)CAS操作核心方法,成功返回true

四、AtomicLong的適用場景

? 推薦使用場景

  • 低并發(fā)的精確計(jì)數(shù)器(如頁面訪問量統(tǒng)計(jì))
  • 需要保證原子性的狀態(tài)標(biāo)記(如下載進(jìn)度百分比)
  • 需要配合其他原子類構(gòu)建復(fù)雜邏輯

不推薦場景

  • 超高并發(fā)計(jì)數(shù)器(考慮LongAdder)
  • 需要保證連續(xù)性的操作(如ID生成)

五、生產(chǎn)環(huán)境實(shí)戰(zhàn)案例

5.1 頁面訪問量統(tǒng)計(jì)

class PageVisitTracker {
    private val visitCount = AtomicLong(0)
    // 注意:這個方法要在后臺線程調(diào)用
    fun trackVisit() {
        visitCount.incrementAndGet()
        if (visitCount.get() % 100 == 0L) {
            uploadToServer() // 每100次上報服務(wù)器
        }
    }
    fun getVisitCount() = visitCount.get()
}

5.2 下載進(jìn)度同步

class DownloadManager {
    private val progress = AtomicLong(0)
    fun updateProgress(bytes: Long) {
        progress.addAndGet(bytes)
        val current = progress.get()
        if (current % (1024 * 1024) == 0L) { // 每MB更新UI
            runOnUiThread { updateProgressBar(current) }
        }
    }
}

六、性能優(yōu)化建議

  • 避免濫用get():頻繁調(diào)用get()會導(dǎo)致緩存失效
  • 慎用lazySet:只有在明確不需要立即可見時使用
  • 注意自旋消耗:高并發(fā)下考慮退避策略或改用LongAdder

七、與LongAdder的抉擇

當(dāng)遇到類似需求時:

when {
    writeQPS < 1000 -> AtomicLong()
    writeQPS > 5000 -> LongAdder()
    else -> 根據(jù)業(yè)務(wù)精度要求選擇
}

八、常見坑點(diǎn)排查

8.1 原子性誤解

錯誤用法:

if (atomicValue.get() > 100) {
    atomicValue.set(0) // 這兩個操作不是原子的!
}

正確姿勢:

while (true) {
    val current = atomicValue.get()
    if (current <= 100) break
    if (atomicValue.compareAndSet(current, 0)) break
}

8.2 數(shù)值溢出問題

val MAX = Long.MAX_VALUE
val counter = AtomicLong(MAX - 10)
repeat(20) {
    counter.incrementAndGet() // 最后會變成Long.MIN_VALUE
}

九、進(jìn)階技巧

9.1 配合Kotlin擴(kuò)展函數(shù)

fun AtomicLong.update(action: (Long) -> Long) {
    while (true) {
        val current = get()
        val newValue = action(current)
        if (compareAndSet(current, newValue)) return
    }
}
// 使用示例
atomicCounter.update { it * 2 }

9.2 性能監(jiān)控方案

class MonitoredAtomicLong(
    initialValue: Long
) : AtomicLong(initialValue) {
    private val casFailureCount = AtomicInteger()
    override fun compareAndSet(expect: Long, update: Long): Boolean {
        val success = super.compareAndSet(expect, update)
        if (!success) casFailureCount.incrementAndGet()
        return success
    }
    fun printStats() {
        Log.d("AtomicStats", "CAS失敗次數(shù):${casFailureCount.get()}")
    }
}

十、總結(jié)

AtomicLong像一把精準(zhǔn)的手術(shù)刀:

  • 優(yōu)勢:精確控制、API豐富、低延遲
  • 局限:高并發(fā)下性能衰減明顯(當(dāng)CAS失敗率>30%時需警惕)

到此這篇關(guān)于Android中的AtomicLong原理、使用與實(shí)戰(zhàn)指南的文章就介紹到這了,更多相關(guān)Android AtomicLong原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android中的Looper對象詳細(xì)介紹

    Android中的Looper對象詳細(xì)介紹

    這篇文章主要介紹了Android中的Looper對象,需要的朋友可以參考下
    2014-02-02
  • Android實(shí)現(xiàn)通用篩選欄

    Android實(shí)現(xiàn)通用篩選欄

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)通用篩選欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Android實(shí)現(xiàn)橫豎屏切換的實(shí)例代碼

    Android實(shí)現(xiàn)橫豎屏切換的實(shí)例代碼

    本篇文章主要介紹了Android實(shí)現(xiàn)橫豎屏切換的實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Android中Canvas的常用方法總結(jié)

    Android中Canvas的常用方法總結(jié)

    在Android自定義View的時候,我們經(jīng)常需要繪制一些自己想要的效果。這里就需要使用Canvas對象。下面這篇文章將Canvas對象常用方法做個筆記,方便自己和大家以后使用的時候查閱,下面來一起看看吧。
    2016-09-09
  • Android開發(fā)Compose框架使用開篇

    Android開發(fā)Compose框架使用開篇

    這篇文章主要為大家介紹了Android開發(fā)Compose框架使用開篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Android自定義相機(jī)界面的實(shí)現(xiàn)代碼

    Android自定義相機(jī)界面的實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了Android自定義相機(jī)界面的實(shí)現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • 解決 INSTALL FAILED CONFLICTING PROVIDER的問題方法

    解決 INSTALL FAILED CONFLICTING PROVIDER的問題方法

    這篇文章主要介紹了解決 INSTALL FAILED CONFLICTING PROVIDER的問題方法的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 故事講解Activity生命周期(貓的一生)

    故事講解Activity生命周期(貓的一生)

    關(guān)于Android中Activity的生命周期,網(wǎng)上大多數(shù)文章基本都是直接貼圖、翻譯API,比較籠統(tǒng)含糊不清。本文主要用故事講解Activity生命周期。下面跟著小編一起來看下吧
    2017-03-03
  • Android自定義ViewGroup實(shí)現(xiàn)標(biāo)簽流效果

    Android自定義ViewGroup實(shí)現(xiàn)標(biāo)簽流效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義ViewGroup實(shí)現(xiàn)標(biāo)簽流效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Android應(yīng)用禁止屏幕休眠的3種方法

    Android應(yīng)用禁止屏幕休眠的3種方法

    這篇文章主要為大家詳細(xì)介紹了Android應(yīng)用禁止屏幕休眠的3種方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11

最新評論