코드 디버깅을 하다가 상황을 발견했는데, 즉 memcached의 연결을 확인해 보니 항상 100개 정도를 유지하고 있는 것을 발견했습니다. 물론 memcached에는 기본적으로 1024개의 연결이 있기 때문에 별 문제는 없을 것 같습니다. 그런데 제가 생각하는 것은 왜 100개 정도인지입니다. memcachedclient가 싱글톤 모드로 생성되었기 때문에 memcachedClientFactory 클래스를 정의했습니다.
개인 MemcachedClientFactory(){
}
개인 MemcachedClientFactory(MemcachedConnectionBuilder memcachedConnectionBuilder, 문자열 서버){
this.memcachedConnectionBuilder= memcachedConnectionBuilder;
this.servers=서버;
}
공개 정적 MemcachedClient createClient(){
if(memcachedClient==null){
this.memcahcedClien= new MemcachedClient(memcachedConnectionBuilder.build(),AddrUtil.get(servers));
}
this.memcahcedClient를 반환합니다.
}
}
}
원래 질문으로 돌아가서 연결 수가 100개가 넘는 이유는 무엇입니까?
위의 작성 방법이 실제로 단 하나의 연결만 생성된다는 것을 보장할 수 있습니까? 당연하지, 왜? 다중 스레드 동시성! 문제는 여기에 있습니다. 여러 스레드가 동시에 createClient() 메서드를 입력하고 모두 memcachedClient가 null이라고 결정하면 여러 연결이 생성됩니다. 하, 문제가 발견되었습니다.
개선하다:
괜찮습니다. 변경 사항은 매우 간단합니다. 프로그램에는 문제가 없으며 연결이 하나만 보장됩니다.
하지만 이 문제를 제쳐두고 싱글톤 모드에서 동시성 문제를 해결하는 방법에 대해 계속 깊이 생각해 볼 수 있습니다.
요약하자면, 싱글톤 모드에서 동시성 문제를 해결하는 방법은 대략 세 가지입니다.
1. 지연된 인스턴스화를 사용하지 말고 조기 인스턴스화를 사용하십시오.
즉, 프로그램은 다음과 같이 다시 작성됩니다.
공개 정적 싱글턴 getInstance(){
반환 인스턴스;
}
}
이렇게 하면 jvm은 클래스를 로딩하자마자 바로 인스턴스를 생성해주기 때문에, 이것의 전제는 인스턴스 생성에 대한 부담이 크지 않고, 성능에 대해서는 별로 생각하지 않으며, 인스턴스가 확실히 생성될 것이라는 점을 확인하는 것입니다. 사용됩니다. 실제로 이전 코드를 다음과 같이 사용할 수도 있습니다.
개인 MemcachedClientFactory(){
}
개인 MemcachedClientFactory(MemcachedConnectionBuilder memcachedConnectionBuilder, 문자열 서버){
this.memcachedConnectionBuilder= memcachedConnectionBuilder;
this.servers=서버;
}
공개 정적 MemcachedClient createClient(){
this.memcahcedClient를 반환합니다.
}
}
}
그러나 문제가 없는 것처럼 보이지만 숨겨진 위험이 있습니다. 즉, 누군가 실수로 memcachedClient.shutdown() 메서드를 호출하면 전체 프로그램이 새로운 memcachedClient를 생성할 수 없게 됩니다. 물론 이는 극단적인 경우이지만 코드 견고성을 위해 다음과 같이 변경할 수 있습니다.
2. 동기화된 키워드를 사용하세요.
이렇게 하면 동기화 문제가 발생할 수 있지만, 동기화를 사용하는 데 따른 오버헤드가 매우 높고 성능에 심각한 영향을 미칠 것이라는 점을 알고 있으므로 이 메서드를 사용하는 전제는 이 메서드를 자주 호출하지 않을 것인지, 아니면 생성에 따른 오버헤드가 발생하는지 확인하는 것입니다. 이 인스턴스는 특별하지 않습니다. 개선될 수 있는지 여부는 아래를 참조하세요.
3. "이중 확인 잠금"을 사용하고 getInstance에서 동기화를 사용합니다.
비공개 싱글턴(){};
공개 정적 싱글턴 getInstance(){
if(인스턴스==null){
동기화됨(Singleton.class){
if(인스턴스==null){
인스턴스=새로운 싱글톤();
}
}
}
반환 인스턴스;
}
}