복붙노트

[SCALA] 스칼라 : 개체 이니셜 라이저에서 병렬 컬렉션 요령에 프로그램을 원인

SCALA

스칼라 : 개체 이니셜 라이저에서 병렬 컬렉션 요령에 프로그램을 원인

난 그냥 방해 행동을 나타났습니다. 하자 내가 유일한 객체로 구성된 독립 프로그램이 말 :

object ParCollectionInInitializerTest {
  def doSomething { println("Doing something") }

  for (i <- (1 to 2).par) {
    println("Inside loop: " + i)
    doSomething
  }

  def main(args: Array[String]) {
  }
}

이 프로그램은 완벽하게 죄이고, 범위는 루프에서 사용될 때 아닙니다 평행 한 다음 출력을 적절히 실행한다 :

병렬 수집 프로그램 적 해봐요 메소드를 호출하지 않고 단지 중단을 사용할 때 불행히도, 출력은 다음되도록 :

그리고 프로그램 중단됩니다. 이것은 단지 불쾌한 버그인가? 나는 스칼라-2.10를 사용하고 있습니다.

해결법

  1. ==============================

    1.이 공사가 완료되기 전에 싱글 개체에 대한 참조를 해제 할 때 스칼라에서 일어날 수있는 고유의 문제이다. 이 때문에 완전히 구축되기 전에 객체 ParCollectionInInitializerTest에 액세스하려는 다른 스레드에 발생합니다. 그것은 주요 방법과는 아무 상관이없는, 오히려, 그것은 main 메소드가 들어있는 개체를 초기화과 관련이있다 -는 REPL에서 표현 ParCollectionInInitializerTest에서 입력을이를 실행하려고하면 동일한 결과를 얻을 수 있습니다. 또한 함께 할 아무것도하지 않습니다 데몬 스레드되는 작업자 스레드를 포크 - 조인.

    이 공사가 완료되기 전에 싱글 개체에 대한 참조를 해제 할 때 스칼라에서 일어날 수있는 고유의 문제이다. 이 때문에 완전히 구축되기 전에 객체 ParCollectionInInitializerTest에 액세스하려는 다른 스레드에 발생합니다. 그것은 주요 방법과는 아무 상관이없는, 오히려, 그것은 main 메소드가 들어있는 개체를 초기화과 관련이있다 -는 REPL에서 표현 ParCollectionInInitializerTest에서 입력을이를 실행하려고하면 동일한 결과를 얻을 수 있습니다. 또한 함께 할 아무것도하지 않습니다 데몬 스레드되는 작업자 스레드를 포크 - 조인.

    싱글 개체가 느리게 초기화됩니다. 모든 싱글 개체는 한 번만 초기화 할 수 있습니다. (귀하의 경우, 메인 쓰레드 단위) 개체에 액세스하는 첫 번째 스레드가 개체의 잠금을 잡아하고 초기화해야 함을 의미한다. 메인 스레드 개체를 초기화하고 결국 잠금을 해제하기 위해 연속적으로 나오는 모든 다른 스레드는 기다려야합니다. 이 싱글 톤 객체는 스칼라에서 구현되는 방법입니다.

    귀하의 경우에는 병렬 수집 작업자 스레드 시도는 해봐요 호출에 단일 개체에 액세스하지만 객체를 초기화 주 스레드가 완료 될 때까지 그렇게 할 수 없습니다 - 그것은 대기 때문에. 반면에, 완료 한 모든 작업자 스레드에 따라 조건으로 병렬 작업이 완료 될 때까지 생성자에서 메인 스레드 대기 - 메인 스레드는 항상 싱글에 대한 초기화 잠금을 보유하고 있습니다. 따라서, 교착 상태가 발생한다.

    아래 그림과 같이, 2.10, 또는 단순한 스레드 선물이 동작이 발생할 수 있습니다 :

    def execute(body: =>Unit) {
      val t = new Thread() {
        override def run() {
          body
        }
      }
    
      t.start()
      t.join()
    }
    
    object ParCollection {
    
      def doSomething() { println("Doing something") }
    
      execute {
        doSomething()
      }
    
    }
    

    REPL이 점을 붙여 넣은 다음 쓰기 :

    scala> ParCollection
    

    그리고 REPL가 중단됩니다.

  2. from https://stackoverflow.com/questions/15176199/scala-parallel-collection-in-object-initializer-causes-a-program-to-hang by cc-by-sa and MIT license