簡體   English   中英

蓄電池是否是線程安全的?

[英]Are accumulators thread-safe?

我正在使用累加器,並想知道這些對象是否是線程安全的?

accumInt是一種AccumulatorParam<Integer>

// Current value accumInt -> 6
AccumulatorThread t1 = new AccumulatorThread();
t1.setAccum(accumInt); 
t1.setValueToAdd(5);

AccumulatorThread t2 = new AccumulatorThread();
t2.setAccum(accumInt);
t2.setValueToAdd(7);

new Thread(t1).start();
new Thread(t2).start();

System.out.println(accumInt.value()); // 11 or 13 or 18

AccumlatorThread類:

class AccumulatorThread implements Runnable {
    Accumulator<Integer> accum;
    Integer              valueToAdd;

    public Integer getValueToAdd() {
        return valueToAdd;
    }


    public void setValueToAdd(Integer valueToAdd) {
        this.valueToAdd = valueToAdd;
    }

    public Accumulator<Integer> getAccum() {
        return accum;
    }


    public void setAccum(Accumulator<Integer> accum) {
        this.accum = accum;
    }

    public void run() {
        System.out.println("Value to Add in Thread : "+valueToAdd);
        accum.add(valueToAdd);
    }
}

該行為表明它不是線程安全的。 我錯過了什么嗎?

OOC為什么要在同一個程序中設置和讀取累加器? 累加器通常由工作線程添加,並且只能由驅動程序線程讀取。

Worker1:   accumulator.add(increment)
Worker2:   accumulator.add(someOtherIncrement)

Driver:  println(accumulator.value)

現在,您要詢問mulithreading在驅動程序的不同線程中設置/讀取值。 為了什么目的? 在這種情況下,只需使用本地JVM AtomicIntegerAtomicLong

累加器是僅通過關聯操作“添加”的變量,因此可以並行有效地支持。

累加器不是線程安全的。 只有SparkContext可以在多個線程中使用。

擴展@javadba@zsxwing的另外兩個很棒的答案。

我對Apache Spark的理解是它們可能是也可能不是線程安全的。 這其實並不重要。 由於驅動程序“遠離”其工作者(它們通常通過網絡或至少在JVM之間相互通信 - 除非它是本地模式)所有對累加器的更新都會到達逐個處理的消息,從而確保單線程更新到累加器。

累加器不是線程安全的,實際上它們不需要是線程安全的。 對於執行程序,累加器是只寫變量,它們可以由執行程序添加,並且可以由驅動程序讀取。 驅動程序使用DAGScheduler.updateAccumulators方法在任務完成后更新累加器的值,並且僅從運行調度循環的線程調用此方法。 一次只處理一個任務完成事件。 這就是為什么不需要累加器是線程安全的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM