2017-12-26 23 views
-1

우리가 싱턴트 클래스를 생성하는 동안 우리가 알고있는 것처럼 우리는 전체 메소드를 동기화 된 것으로 만들거나 객체의 생성을 책임지는 명령문의 블록만을 동기화로 만듭니다. 그러나이 두 접근법 중 더 좋고 왜?동기화 된 메서드 또는 동기화 된 블록 : java에서 singleton 클래스를 작성하는 동안 어느 쪽이 더 낫습니까?

접근 한

public static A getA(){ 
    if (obj == null){ 
     synchronized(Singleton.class) { 
      if (obj == null) { 
       obj = new Singleton();//instance will be created at request time 
      } 
     } 
    } 
    return obj; 
} 

접근법 2

public synchronized static A getA(){ 
    if (obj == null){ 
     obj = new Singleton();//instance will be created at request time 
    } 
    return obj; 
} 
+0

싱글 톤이 좋지 않기 때문에 아무 문제가 없습니다. –

+1

@SleimanJneidi 왜 싱글 톤이 좋지 않은가요? –

+0

나중에 알겠지만이 두 가지 중 어떤 것이 더 나은지 설명해 주시겠습니까? –

답변

1

개념 :

public synchronized static A getA(){ 
    if (obj == null){ 
     obj = new Singleton();//instance will be created at request time 
    } 
    return obj; 
} 

(위의 예처럼)하는 방법에 동기화 키워드를 사용하여 일반적으로 매우 안전하지만 전체 방법에 대한 액세스를 동기화 당신은 아주 작은 방법 당신이없는 경우 당신이 절대적으로 필요로하는 것보다 더 많은 코드 덩어리를 동기화 할 수 있습니다. 이는 필요한 것보다 더 많은 성능 저하입니다. 동기화 된 블록/메소드는 한 번에 하나의 스레드에서만 액세스 할 수 있기 때문에 실제로 처리 속도가 느려집니다. 동기화하는 코드 덩어리가 클수록 성능이 저하됩니다. 당신이로드 게으른 단 하나의 자원이 필요한 경우

, 당신은 같은 것을 할 필요가 : 여기

class MyClass { 
     private static volatile Resource resource; 
     private static final Object LOCK = new Object(); 

     public static Resource getInstance() { 
      if(resource == null) { 
       synchronized(LOCK) { // Add a synch block 
        if(resource == null) { // verify some other synch block didn't 
              // write a resource yet... 
         resource = new Resource(); 
        } 
       } 
      } 
      return resource; 
     } 
} 

하나 개 중요한 것은 앱에서 전체 스레드에 대한 volatile 수정 제공하는 가시성 .

1

obj가 null이 아닌 경우 두 번째 방법은 때마다 잠금을 획득하면서, 잠금을 획득하지 않기 때문에 첫 번째가 더 낫다 .

1

두 번째 검사 잠금을 사용하는 첫 번째 검사를 수행합니다.

은 아마 당신은이 같은 시도 할 수 있습니다 :

public class MySingleton { 
     private static instance = new MySingleton(); 
     private MySingleton(){ } 
     public MySingleton getInstance { 
      return instance; 
     } 
} 
1

당신보다 효율적으로 사용 홀더 관용구 줄을

public class HolderFactory { 
    public static Singleton get() { 
     return Holder.instance; 
    } 

    private static class Holder { 
    public static final Singleton instance = new Singleton(); 
    } 
} 

인스턴스가 get()에 첫 번째 호출에 만들어지고 그것이되기 때문에 그것은 게으른 클래스가 단일 스레드에서 클래스 로더에 의해로드되도록 보장되기 때문에 스레드로부터 안전합니다. 또한 싱글 톤 및 스레드 안전성에 대한 자세한 내용은이 링크를 확인하십시오. https://shipilev.net/blog/2014/safe-public-construction/