1

나는 누산기를 사용하고 있으며 이러한 객체가 스레드로부터 안전한지 알고 싶습니까?축전지는 thread로부터 안전한가요?

accumIntAccumulatorParam<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); 
    } 
} 

동작이 안전하게 스레드 아니라는 것을 보여줍니다. 내가 놓친 게 있니?

답변

4

누산기는 스레드로부터 안전하지 않습니다. SparkContext 만 여러 스레드에서 사용할 수 있습니다.

4

OOC 왜 같은 프로그램에서 누산기를 설정하고 읽는 중입니까? 누적 기는 일반적으로 작업자 스레드에 의해 추가되며 드라이버 스레드에서만 읽을 수 있습니다.

Worker1: accumulator += increment 
Worker2: accumulator += someOtherIncrement 

Driver: println(accumulator.value) 

이제 드라이버의 다른 스레드에서 값을 설정/읽을 때 mulithreading에 대해 묻습니다. 무슨 목적으로? 이 경우 로컬 JVM AtomicInteger 또는 AtomicLong 만 사용하십시오.

어큐뮬레이터는 연관 연산을 통해서만 "추가"되는 변수이므로 효율적으로 병렬로 지원할 수 있습니다.

1

@javadba@zsxwing에서 다른 두 가지 대답을 확장하십시오.

Apache Spark에 대한 제 이해는 스레드로부터 안전 할 수도 있고 그렇지 않을 수도 있다는 것입니다. 이 아니라이 중요합니다. 드라이버는 직원들과 "멀리 떨어져 있기 때문에"(그들은 보통 네트워크를 통해 또는 적어도 JVM 사이에서 서로 이야기합니다 - 로컬 모드가 아니면) 누적 계산기에 대한 모든 업데이트는 하나씩 처리되는 메시지에 도착하므로 누산기에 대한 단일 스레드 갱신.

+0

로컬 모드에서 테스트를 실행해도 상관이 없습니까? –

+0

드라이버와 유일한 실행 프로그램이 분리되어 있기 때문에 (동일한 JVM에서 작동합니다.) –

0

누산기는 스레드로부터 안전하지 않으며 실제로는 스레드로부터 안전하지 않아도됩니다. 실행 프로그램의 경우 누적 기는 쓰기 전용 변수이며 실행 프로그램에서 추가 할 수 있으며 드라이버에서 읽을 수 있습니다. 드라이버는 DAGScheduler.updateAccumulators 메서드를 사용하여 작업 완료 후 누적 기의 값을 업데이트하며이 메서드는 일정 루프를 실행하는 스레드에서만 호출됩니다. 한 번에 하나의 타스크 완료 이벤트 만 처리됩니다. 이것이 누적 기가 스레드로부터 안전 할 필요가없는 이유입니다.