第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

原子操作之 LongAccumulator

1. 前言

今天為大家介紹原子操作之 LongAccumulator。此工具位于 java.util.concurrent.atomic 包中。

本節(jié)先介紹 LongAccumulator 工具類的基本概念和最基本用法,之后給出 LongAccumulator 工具類最常用的場合說明,然后通過簡單的編碼實現(xiàn)一個實際案例,最后帶領(lǐng)大家熟悉 LongAccumulator 最常用的一些編程方法,讓大家進一步加深對 LongAccumulator 工具類的理解。

下面我們正式開始介紹吧。

2. 概念介紹

相比 LongAdder,LongAccumulator 工具類提供了更靈活更強大的功能。不但可以指定計算結(jié)果的初始值,相比 LongAdder 只能對數(shù)值進行加減運算,LongAccumulator 還能自定義計算規(guī)則,比如做乘法運行,或其他任何你想要的計算規(guī)則。這樣描述是不是有點抽象,別著急,看下面的圖示。
圖片描述
我們看下面 LongAccumulator 工具類的基本用法。

3. 基本用法


// 首先創(chuàng)建一個雙目運算器對象,這個對象實現(xiàn)了計算規(guī)則。
LongBinaryOperator longBinaryOperator = new LongBinaryOperator() {
        @Override
        public long applyAsLong(long left, long right) {
            ...
        }
    }

// 接著使用構(gòu)造方法創(chuàng)建一個 LongAccumulator 對象,這個對象的第1個參數(shù)就是一個雙目運算器對象,第二個參數(shù)是累加器的初始值。
LongAccumulator longAccumulator = new LongAccumulator(longBinaryOperator, 0);
...
// 調(diào)用累加方法
longAccumulator.accumulate(1000)
// 調(diào)用結(jié)果獲取方法
long result = longAccumulator.get();
...

是不是簡單又強大!LongAccumulator 在我們?nèi)粘嵺`中,到底應(yīng)該應(yīng)用在哪些場合比較合適呢?下面我們給出最常用的場景說明。

4. 常用場景

LongAccumulator 經(jīng)常用于自定義運算規(guī)則場景下的多線程并發(fā)場合。一些簡單的累加計算可以直接使用我們之前課程中介紹的工具類,但是當(dāng)運行規(guī)則比較復(fù)雜或者 JDK 沒有提供對應(yīng)的工具類時,可以考慮 LongAccumulator 輔助實現(xiàn)。當(dāng)然所有可使用 LongAdder 的場合都可使用 LongAccumulator 代替,但是沒有必要。

下面我們用 LongAccumulator 工具類實現(xiàn)上一節(jié)中的生活實例,為了簡化敘述,本節(jié)我們只統(tǒng)計男性客戶總數(shù)量。請看下面的代碼。

5. 場景案例

import java.util.concurrent.atomic.LongAccumulator;

public class LongAccumulatorTest {

	// 此處的運算規(guī)則是累加,所以創(chuàng)建一個加法雙目運算器對象作為構(gòu)造函數(shù)的第一個參數(shù)。
    // 將第二個參數(shù)置為0,表示累加初始值。
    // maleCount 對象代表當(dāng)天所有進入商場的男性客戶總數(shù)量。
    private static LongAccumulator maleCount = new LongAccumulator(new LongBinaryOperator() {
	    // 此方法用于實現(xiàn)計算規(guī)則
        @Override
        public long applyAsLong(long left, long right) {
	        // 在本例中使用加法計算規(guī)則
            return left + right;
        }
    }, 0);

    public static void main(String[] args) {
        // 定義30個商場入口檢測設(shè)備
        for (int i = 1; i <= 30; i++) {
            MonitoringDevice monitoringDevice = new MonitoringDevice(maleCount, i);
            // 開啟檢測設(shè)備進行檢測
            new Thread(monitoringDevice).start();
        }
    }
}

在上面的代碼中,首先創(chuàng)建一個 LongAccumulator 對象表示統(tǒng)計結(jié)果,然后創(chuàng)建了 30 個商場入口檢測設(shè)備模擬檢測識別,接下來每個檢測設(shè)備如何動作呢,看下面的代碼。

import java.util.Random;
import java.util.concurrent.atomic.LongAccumulator;

/**
 * 模擬設(shè)備
 */
public class MonitoringDevice implements Runnable {
    private LongAccumulator maleCount;
    private String monitoringDeviceNo;
    public MonitoringDevice(LongAccumulator maleCount, int monitoringDeviceNo) {
        this.maleCount = maleCount;
        this.monitoringDeviceNo = "第" + monitoringDeviceNo + "監(jiān)控采集處";
    }
    
	/**
	 * 設(shè)備運行的處理邏輯
	 */
    public void run() {
        while (true) {
            // 監(jiān)測處理 (監(jiān)測設(shè)備輸出1代表男性,0代表女性,其他代表未能識別,此處隨機產(chǎn)生監(jiān)測結(jié)果)
            try {
                Thread.sleep(new Random().nextInt(3000));
            } catch (Exception e) {}
            int monitoringDeviceOutput = new Random().nextInt(3);

            // 對監(jiān)測結(jié)果進行統(tǒng)計
            switch (monitoringDeviceOutput) {
                case 1: maleCount.accumulate(1);
                    System.out.println("統(tǒng)計結(jié)果: maleCount=" + maleCount.get());
                    break;
                default:
                    System.out.println("忽略統(tǒng)計");
                    break;
            }
        }
    }
}

在 MonitoringDevice 類中,首先模擬監(jiān)測設(shè)備輸出,然后將輸出結(jié)果使用 add () 進行統(tǒng)計累加,使用 sum () 輸出累加結(jié)果。運行一段時間后運行結(jié)果如下。

...
忽略統(tǒng)計
統(tǒng)計結(jié)果: maleCount=50
...

上面的示例中,使用 LongAccumulator 實現(xiàn)了上一節(jié)中相同的需求。對比觀察,能夠體會到 LongAccumulator 工具類更靈活的地方,但同時也更復(fù)雜一些。

至此,大家對 LongAccumulator 已經(jīng)有了初步的理解,接下來我們繼續(xù)豐富對 LongAccumulator 工具類的認識。

6. 核心方法介紹

除過上面代碼中使用的最基本的 accumulate (int)、get () 方法之外,我們再介紹兩個方法的使用。

  1. reset () 方法

將累加器值置為 0,即為后繼使用重新歸位。

  1. getThenReset () 方法

此方法邏輯等同于先調(diào)用 get () 方法再調(diào)用 reset () 方法。

7. 小結(jié)

本節(jié)通過一個簡單的例子,介紹了 LongAccumulator 的基本用法。在 java.util.concurrent.atomic 包中還存在類似的工具類,如 DoubleAccumulator,用法大同小異,希望大家在日常研發(fā)中多比較多總結(jié),早日掌握之。