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

原子操作之 LongAccumulator

1. 前言

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

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

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

2. 概念介紹

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

3. 基本用法


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

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

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

4. 常用場景

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

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

5. 場景案例

import java.util.concurrent.atomic.LongAccumulator;

public class LongAccumulatorTest {

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

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

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

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è)備運(yùn)行的處理邏輯
	 */
    public void run() {
        while (true) {
            // 監(jiān)測(cè)處理 (監(jiān)測(cè)設(shè)備輸出1代表男性,0代表女性,其他代表未能識(shí)別,此處隨機(jī)產(chǎn)生監(jiān)測(cè)結(jié)果)
            try {
                Thread.sleep(new Random().nextInt(3000));
            } catch (Exception e) {}
            int monitoringDeviceOutput = new Random().nextInt(3);

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

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

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

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

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

6. 核心方法介紹

除過上面代碼中使用的最基本的 accumulate (int)、get () 方法之外,我們?cè)俳榻B兩個(gè)方法的使用。

  1. reset () 方法

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

  1. getThenReset () 方法

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

7. 小結(jié)

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