나는 하나의 클래스 인스턴스가 생성되지 않도록 자바에서 싱글 톤 클래스를 구현 중이다.싱글 톤 클래스를 threadsafe로 만드는 방법은 무엇입니까?
답변
아마 가장 좋은 방법은 단일 인스턴스와 함께 enum을 사용하는 것입니다. 직렬화 및 반사에 대한 단일성을 보장하는 추가 된 이점이 있습니다. 이는 "단순한"Singleton 구현이 수행하지 않습니다 (비공개입니까? 반영 여부, 액세스 수정자를 비웃음).
싱글 톤은 기본적으로 스레드 안전하지 않습니다. 싱글 톤을 만드는 일반적인 방법은 하나의 인스턴스 생성을 처리하는 팩토리 메소드를 갖는 것입니다. 그렇게하면 인스턴스 생성을 제어 할 수 있습니다.
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton() { ... }
}
"Holder"클래스보다 정적 인스턴스 변수를 사용하는 것이 좋습니다. 원한다면 정적 멤버를 private으로 만들고 액세스 할 수있는 메서드를 제공 할 수 있습니다.하지만 스택에 다른 메서드 호출을 추가하는 것뿐입니다.
무엇이 더 좋습니까? 홀더가 당신에게 게으른 싱글 톤을 제공합니다. 더 간단한 버전은 게으른 로딩을 제공하지 않습니다. –
예. Java는 처음 사용될 때까지 클래스를로드하지 않습니다. –
전혀 사실이 아닙니다. 처음 참조 할 때로드합니다 (예 : 다른 클래스의 메소드 서명. – skaffman
게으른 인스턴스화 : getInstance()는 싱글 톤을 반환하거나 첫 번째 호출 인 경우 생성합니다.
public class MySingleton
{
private static MySingleton instance;
private MySingleton()
{
// construct object . . .
}
// For lazy initialization
public static synchronized MySingleton getInstance()
{
if (instance==null)
{
instance = new MySingleton();
}
return instance;
}
// Remainder of class definition . . .
}
게으른 인스턴스 생성은 거의 필요하지 않습니다. 그렇다면 Java는 클래스를 지연로드합니다. 따라서 선언에서 인스턴스를 실제로 만들면 * 지연 오버플로없이 지연 인스턴스화가 발생합니다 (매우 드물지만 게으름이 아니며 skaffman의 대답이 더 좋음) . –
또한이 구현은 인스턴스에 대한 참조를 얻기위한 모든 시도를 동기화합니다. 대부분의 코드는 다음과 같이 동작합니다 : Singleton.getInstance.doSomething(); Singleton.getInstance.doSomethingElse(); 전반적인 효과는 멤버 액세스/변경의 관점에서 스레드 안전성을 보장하지 않으면 서 동시성을 심각하게 제한하는 추가 동기화입니다. –
java에서 이중 확인 잠금이 깨졌습니다. http://www.javaworld.com/jw-0220001/jw-0209-double.html 간단히 말해서이 클래스가 한 번만 인스턴스화 될 수 있음을 보장하는 방법은 다음과 같습니다. 찾기 힘든 동시성 문제. 이것을 절대 사용하지 마십시오. – Buhb
싱글 톤을 만드는 가장 좋은 방법은 무엇입니까? 열거 형을 사용하십시오.
public enum Singleton {
INSTANCE;
public void foo(){ ... }
}
// Usage:
Singleton.INSTANCE.foo();
이중 인스턴스화를 방지 할뿐만 아니라 비 직렬화 손상을 피하는 데 많은 도움을 얻습니다.
동시성에 관심이있는 경우 공유 전역 상태를 사용하지 않습니다.
싱글 톤이 단일 병렬화 된 문제에서 누적 된 결과를 보유하고 있다면 왜 그렇지 않습니까? 싱글 톤 (singleton)은 글로벌 상태를 요약하며, 공정한 사용 시나리오입니다. –
프로세스간에 공유되는 인스턴스가 하나만있는 클래스로 여러 사용 사례가 있습니다.스프링을 사용하는 잘 설계된 일반적인 웹 애플리케이션은 싱글 톤 범위에서 인스턴스화 된 클래스를 작업자 스레드간에 공유 할 수 있습니다. – Buhb
액세스 수정자를 비난하는 +1. 나는 lol'd. :) – corsiKa