2011-03-04 7 views
5

나는 stateful 싱글 톤에 대한 호출을 위임 한 액터가 있습니다. 싱글 톤은 객체 맵을 유지 관리하므로 상태 저장이 가능합니다. 이 싱글 톤 객체는 액터와 클래스에서 (액터가 아닌)이 맵에서 하나의 객체를 검색하는 곳에서 사용됩니다 (따라서 스레드로부터 안전하게 읽음).akka scala 액터의 싱글 톤 사용

class MyActor extends Actor{ 
    def receive()={ 
    case ACase => singleton.amethod() 
    case BCase => singleton.bmethod() 
    } 
} 

val singleton = new MyActorLogic 

class MyActorLogic{ 
val map:Map[String, Object] = Map() 
def amethod()=//alter the map 

def readMap(value:String) = map(value) }     

부작용/문제가있을 수 있습니까? 감사합니다

답변

9

하지는 세계에서 어떤 이유로 그렇게 마십시오. 나를 믿어 라.

당신이 일의 종류가 필요한 경우

는 그들이 좋은 무엇이다, 대신 에이전트를 사용 :

http://doc.akka.io/docs/akka/2.0.4/scala/agents.html

+0

지도에 액터를 넣고 액터에 쿼리를 수행했습니다. 따라서 싱글 톤은 배우에게 통합되어 아무것도 노출시키지 않습니다. 나는 배우와 의존성 주입이 좋은 친구가 아니라고 생각하기 시작했습니다. 내가 맞습니까? – Matroska

+2

DI는 잘 작동하지만 Spring 통합과 Guice 통합도 있습니다. –

+1

간단한 설명을하면 훨씬 더 유용한 대답이 될 것입니다. 질문에 접근하지 않은 이유는 무엇입니까? 액터에서 맵을 캡슐화하거나 에이전트를 사용하는 것보다 왜 열등합니까? – mahonya

3

이론상으로, 복수 스레드의 간단한 변경 가능한 맵으로 무장 한 MyActorLogic을 사용하면 다른 스레드가 맵을 변경하는 동안 한 스레드가 맵을 가로 지르는 경우 동시 변경 예외가 발생할 수 있습니다.

당신은 문제를 방지하기 위해 다음을 수행 할 수 :

  1. 은 (개인 회원으로) 배우로지도를 넣습니다. Akka에서는 Actor 인스턴스를 직접 사용하지 않고 프록시를 통해 액세스합니다 (ActorRef). 이 경우 맵에 안전하게 액세스 할 수있을뿐 아니라 항상 한 번에 하나의 메시지 만 처리하는 액터가 보장합니다. 다른 스레드는 리플렉션을 통해서도 개인 멤버에 액세스 할 수 없습니다.
  2. 당신은 MyActorLogic 스레드 안전
  3. 당신이 var map:immutable.Map을 사용할 수 있습니다 당신은 오래된 좋은 ConcurrentHashMap
  4. 대신 val map:mutable.Map의를 사용할 수 있습니다 (예를 들어, 그들 synchronized 제작)의 갱신/검색 방법을 만들 수 있습니다. 따라서 map에 액세스하는 다중 스레드는 종종 부실 데이터와 함께 작동하지만 동시에 수정되지는 않습니다 (copy-on-write 접근법).

그냥 참고, 진정한 싱글은 다음과 같습니다

object MyActorLogic{ 
val map:Map[String, Object] = Map() 
... 
+0

는 내가 처음 제안을 따를 것이다. 객체가 단위 테스트를 위해 mockable이 아니기 때문에 new 연산자를 사용하고 있습니다. 하지만 저는 케이크 패턴을 사용하고 있습니다. 아마도 케이크 패턴으로 물건을 조롱 할 수있을 것입니다. 고마워요. – Matroska

+0

나는 결코 그런 것을 추천하지 않을 것입니다. 그것은 단지 문제를 간청하고 있습니다. –