2014-10-25 3 views
0
public static Database getInstance() 
{ 
    if(instance == null) 
    { 
     return instanceNotFoundDoubleCheckSynced(); 
    } 
    return instance; 
} 


synchronized private static Database instanceNotFoundDoubleCheckSynced() 
{ 
    if(instance == null) 
    { 
     Connection connection = establishConnection(); 
     if(connection != null) 
     { 
      instance = new Database(connection); 
     } 

    } 

위 코드는 먼저 데이터베이스 연결 인스턴스를 얻으려고합니다. 그렇게 할 수 없다면, 동기화 된 메소드에 들어가서 다시 점검하고, 인스턴스가없는 경우 새로운 메소드를 작성합니다.다중 스레드로 데이터베이스 연결을 하나만 만들려고합니다.

두 가지 방법을 확인하는 이유는 첫 번째 동기화되지 않고 많은 스레드가 동시에 실행할 수 있지만 실제로 동시에 새 연결을 만드는 메서드를 실행하는 스레드를 원하지 않기 때문입니다.

내 문제는 일단 스레드가 instanceNotFoundDoubleCheckSynced 메소드에 도달하면 모든 스레드가 인스턴스를 실행할 기회를 기다리는 것입니다.

아무도 내가이 문제를 해결할 수있는 방법을 제안 할 수 있습니까? 데이터베이스 연결이 설정되기 전에 많은 호출이이 메소드에 올 것 같지 않기 때문에 프로덕션 환경에서 문제가 될 것이라고 생각하지 않지만 JUnits에는 10,000 개의 스레드가 실행되고 모두 막혔습니다.

감사합니다.

+0

요즘 싱글 톤은 나쁜 관행이되고 있습니다. 귀하의 프로젝트에 싱글 톤 솔루션을 구현하는 것을 권장하지 않습니다. – christopher

+1

이 디자인을 계속 사용하려면이 디자인을 사용하십시오. 한 가지 조언은 시작할 때 코드를 실행하는 것입니다. 웹 앱이 발생하면 리스너를 만들어서 할 수 있습니다. 또한 원격 서버를 복구 할 때 어떤 일이 발생할지 생각해보십시오. 이것이 싱글 톤이기 때문에 당신은 당신의 jvm을 다시 시작해야합니까? – jitsonfire

답변

0

올바른지 확인하기가 쉽지 않으므로 이중 확인 잠금을 사용하지 마십시오. Initialization-on-demand holder idiom을 사용하면 내부 클래스에서 직접 공유 객체를 인스턴스화하는 것이 더 좋을 것이라고 생각합니다. 더 간단하고 효율적입니다.

0

저는 모든 스레드가 시작되어 연결을 시도하는 비현실적인 시나리오를 테스트하고 있다고 생각합니다. a) 연결에 시간이 걸리기 때문에 b) 동시에 많은 스레드가 시작되므로 모두 동기화되지 않은 검사를 통과하고 동기화 된 호출을 기다리게됩니다. 테스트 스레드의 수를 실제 수치 (100-200)로 설정하고 스레드를 시작할 때 임의의 지연을 추가하는 것이 좋습니다.

또한, 당신은 당신이 하나의 방법으로 다시 확인 단순화하고 적절한 오류 처리를 추가 할 수 있습니다 :이 도움이

class MyClass { 

    public static Database getInstance() 
    { 
     if(instance == null) 
     { 
      synchronized (MyClass.class) 
      { 
      if(instance == null) 
      { 
       Connection connection = establishConnection(); 
       if(connection == null) 
       { 
        throw new RuntimeException("Cannot establish connection"); 
       } 
      } 

      instance = new Database(connection); 
      } 
     } 

     return instance; 
    } 
} 

희망을.

Slave Imeshev