2013-07-24 2 views
6

우리는 Scala, Play 프레임 워크 및 MongoDB (ReactiveMongo를 드라이버로 사용)로 웹 응용 프로그램을 구축하고 있습니다. 애플리케이션 아키텍처는 엔드 - 투 - 엔드 블로킹이 아닙니다.향후 코드에서 동기화/잠금 사용

우리 코드의 일부에서는 스칼라의 파서 연결자, 스칼라의 반사 등과 같은 스레드로부터 안전하지 않은 라이브러리에 액세스해야합니다. 우리는 현재 이러한 호출을 synchronized 블록으로 묶고 있습니다. 나는 두 가지 질문이 있습니다

  1. 미래 Y 코드 synchronized을 이용할 때는 어떤 개는이 있습니까?
  2. synchronized 대신 잠금 (예 : ReentrantLock)을 사용하는 것이 성능 및 사용성 측면에서 더 좋습니까?
+0

"미래 코드" – fge

+0

@fge가 의미하는 바를 이해하는 데 어려움이 있습니다. 코드는 '미래'를 많이 사용합니다. 나는 그것이 컨텍스트 (Play, Reactive * 등)에서 충분히 명확하다고 생각했지만, 그렇지 않은 것 같아 사과합니다. – missingfaktor

+1

기본 실행 컨텍스트로 차단 작업을 수행하면 안됩니다. [이 답변] (http://stackoverflow.com/a/16834855/406435) 유용 할 수 있습니다. – senia

답변

2

예를 들어 리플렉션 및 구문 분석은 합리적으로 변경할 수 없어야하며 잠금 할 필요는 없습니다.하지만 잠금을 사용하려는 경우 동기화 된 블록이 수행합니다. 나는 동기화 대 잠금을 사용하는 것 사이에 성능 차이가별로 없다고 생각한다.

8

) 예) using-actors-instead-of-synchronized을 참조하십시오. 즉이 잠금 대신 배우를 사용하는 것이 더 바람직 할 것입니다 : 당신이 대신 log.info의 원하는하지 스레드 안전 코드를 삽입 할 수 있습니다

class GreetingActor extends Actor with ActorLogging { 

    def receive = { 
    case Greeting(who) ⇒ log.info("Hello " + who) 
    } 
} 

하나의 메시지가 지정된 시간에 처리됩니다, 모든 것이 정상적으로 작동합니다. BTW에서는 ask 패턴을 사용하여 배우가 미래를 필요로하는 기존 코드에 원활하게 통합 될 수 있습니다.

+0

"문의 패턴"이 무엇이며 어떻게 사용하는지 자세히 설명해 주실 수 있습니까? – missingfaktor

+1

나는 공식 문서 http : //doc.akka보다 잘 할 수 없었다.io/docs/akka/snapshot/scala/actors.html # Ask__ 수신 - 수신 - 미래 – vitalii

3

내게있어서 주요 문제는 동기화 된 코드 섹션이나 잠긴 섹션을 ​​호출하면 실행 컨텍스트의 스레드가 막히고 마비 될 수 있다는 것입니다. 이 문제를 방지하려면, 당신은 scala.concurrent.blocking를 사용하여 잠재적으로 차단하는 방법으로 모든 통화를 마무리 할 수 ​​

물론
import scala.concurrent._ 
import ExecutionContext.Implicits.global 

def synchronizedMethod(s: String) = synchronized{ s.size } 

val f = future{ 
    println("Hello") 
    val i = blocking{ //Adjust the execution context behavior 
    synchronizedMethod("Hello") 
    } 
    println(i) 
    i 
} 

, 배우 내부 시리얼 코드 스레드 로컬 변수 나 포장 호출과 같은 대안을 고려하는 것이 더 좋을 수 있습니다.

마지막으로 잠금 대신 동기화를 사용하는 것이 좋습니다. 대부분의 응용 프로그램 (특히 중요한 섹션이 큰 경우)에서는 성능 차이가 눈에 띄지 않습니다.

+1

+1 (blocking)() 팁. 잠금 폴링, 타임 아웃, 인터럽트 가능성 등을 이용하기를 원하지 않는 한'synchronized' 사용에 동의했습니다. – sourcedelica

2

글쎄, 가장 쉽고 안전한 방법은 (가능하다면) 스레드 감금 일 것입니다. 즉, 각 스레드는 파서 연결자 등의 자체 인스턴스를 생성 한 다음이를 사용합니다.

동기화가 필요하면 (트래픽이 발생하면 피하는 것이 좋습니다) synchornized 또는 ReentrantLock은 거의 동일한 성능을 제공합니다. 어떤 객체가 잠금 장치가 필요한지에 따라 달라집니다. 웹 응용 프로그램에서 절대적으로 필요한 경우가 아니면 권장하지 않습니다.

+0

스레드 감금을 수행하는 방법에 대한 자세한 정보를 제공해 주시겠습니까? – missingfaktor