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

原子操作之 DoubleAdder

1. 前言

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

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

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

2. 概念介紹

DoubleAdder 工具類采用了 “分頭計算最后匯總” 的思路,避免每一次(細粒度)操作的并發(fā)控制,提高了并發(fā)的性能。什么是細粒度的同步控制呢?所謂細粒度的同步控制,指的是對待同步控制對象的每一次操作都需要加以控制,這樣描述是不是有點抽象,別著急,看下面的圖示。
圖片描述
我們看下面 DoubleAdder 工具類的基本用法。

3. 基本用法

// 首先創(chuàng)建一個 DoubleAdder 對象
DoubleAdder doubleAdder = new DoubleAdder();
...
// 調(diào)用累加方法
doubleAdder.add(50.5);
doubleAdder.add(49.5);
// 調(diào)用求和方法
double sum = doubleAdder.sum();
...

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

4. 常用場景

DoubleAdder 經(jīng)常用于多線程并發(fā)做收集統(tǒng)計數(shù)據(jù)的場合,而不是細粒度的同步控制。
下面我們用 DoubleAdder 工具類實現(xiàn)一個生活案例:某商場為了掌握客流特征,在商場所有出入口架設(shè)了人體特征識別設(shè)備,此類設(shè)備可以有效識別客人性別等信息?;诖耍虉龉芾磙k公室計劃制作一個客流性別流量圖表,用于決策商場的服務(wù)內(nèi)容。

5. 場景案例

import java.util.concurrent.atomic.DoubleAdder;

public class DoubleAdderTest {

    // 首先創(chuàng)建三個 DoubleAdder 對象分別表示統(tǒng)計結(jié)果
    // 代表當(dāng)天所有進入商場的男性客戶總數(shù)量
    private static DoubleAdder maleCount = new DoubleAdder();
    // 代表當(dāng)天所有進入商場的女性客戶總數(shù)量
    private static DoubleAdder womenCount = new DoubleAdder();
    // 代表當(dāng)天所有進入商場的未能識別的客戶總數(shù)量
    private static DoubleAdder unknownGenderCount = new DoubleAdder();
	
    public static void main(String[] args) {
        // 定義30個商場入口檢測設(shè)備
        for (int i = 1; i <= 30; i++) {
            MonitoringDevice monitoringDevice = new MonitoringDevice(maleCount, womenCount, unknownGenderCount, i);
            // 開啟檢測設(shè)備進行檢測
            new Thread(monitoringDevice).start();
        }
    }
}

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

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

public class MonitoringDevice implements Runnable {

    private DoubleAdder maleCount;
    private DoubleAdder womenCount;
    private DoubleAdder unknownGenderCount;

    private String monitoringDeviceNo;

    public MonitoringDevice(DoubleAdder maleCount, DoubleAdder womenCount, DoubleAdder unknownGenderCount, int monitoringDeviceNo) {
        this.maleCount = maleCount;
        this.womenCount = womenCount;
        this.unknownGenderCount = unknownGenderCount;
        this.monitoringDeviceNo = "第" + monitoringDeviceNo + "監(jiān)控采集處";
    }

    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 0: womenCount.add(1); 
                    System.out.println("統(tǒng)計結(jié)果: womenCount=" + womenCount.sum());
                    break;
                case 1: maleCount.add(1); 
                    System.out.println("統(tǒng)計結(jié)果: maleCount=" + maleCount.sum());
                    break;
                default: unknownGenderCount.add(1);
                    System.out.println("統(tǒng)計結(jié)果: unknownGenderCount=" + unknownGenderCount.sum());
                    break;
            }
        }
    }
}

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

...
統(tǒng)計結(jié)果: unknownGenderCount=23.0
統(tǒng)計結(jié)果: womenCount=24.0
統(tǒng)計結(jié)果: maleCount=32.0
...

上面的案例中,總共計算了三個統(tǒng)計值,每一個統(tǒng)計值都使用了多個線程同時進行統(tǒng)計計算。在統(tǒng)計過程中,每一個線程只需要累加自己的那份統(tǒng)計結(jié)果,所以不需要做同步控制,只要在最后進行匯總統(tǒng)計結(jié)果時做同步控制進行匯總即可。像這樣的場景使用 DoubleAdder 工具類會非常方便簡潔。

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

6. 核心方法介紹

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

  1. reset () 方法

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

  1. sumThenReset () 方法

此方法邏輯等同于先調(diào)用 sum () 方法再調(diào)用 reset () 方法,簡化代碼編寫。

7. 小結(jié)

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