아래의 클래스를 살펴보고 아래 코드가 스레드로부터 안전한지 말해보십시오. 요점은 내 static
메서드와 그 메서드가 singleton 인스턴스의 메서드를 호출하는 한 클래스입니다. 또한 Runnable
인스턴스가 static
메서드를 호출합니다. 그래서 코드를 보도록 요청하고 있습니다 - static
메소드이고 멀티 스레드 환경에서 싱글 톤의 메소드를 호출합니다 - 안전합니까?싱글 톤 및 멀티 스레드
내 질문에 답변 해 주시면 정말 감사하겠습니다. 본질적으로
Thread 1 Thread 2
-------- --------
test instance != null
test instance != null
finds it is
finds it is
creates, assigns
creates, assigns
returns
returns
, 이것은 더 이상 싱글되지 않습니다 :이 시나리오가 발생할 수 있기 때문에
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
public class SingletonCls {
private static SingletonCls singletonInstance = null;
private SingletonCls() {
}
public static SingletonCls getIntance() {
if (SingletonCls.singletonInstance == null) {
singletonInstance = new SingletonCls();
}
return SingletonCls.singletonInstance;
}
public List<Map<String, String>> call(String id) throws Exception {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
BufferedReader br = null;
final String col = "col";
try {
br = new BufferedReader(new FileReader("test.txt"));
String lineStr = null;
while ((lineStr = br.readLine()) != null) {
StringTokenizer st = new StringTokenizer(lineStr, ",");
int colIdx = 1;
if (lineStr.startsWith(id)) {
Map<String, String> map = new HashMap<String, String>();
while (st.hasMoreTokens()) {
String value = st.nextToken();
map.put(col + (colIdx++), value);
}
list.add(map);
}
}
} finally {
if (br != null) {
br.close();
}
}
return list;
}
}
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class TestSingleTonCaller {
public static List<Map<String, String>> getData(String id) throws Exception {
List<Map<String, String>> list = SingletonCls.getIntance().call(id);
return list;
}
}
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class RunnableSingleTonExe implements Runnable {
private final String id;
public RunnableSingleTonExe(String inId) {
this.id = inId;
}
public void run() {
try {
List<Map<String, String>> list = TestSingleTonCaller
.getData(this.id);
System.out.println("thread id:" + this.id + " list > "
+ (list == null ? "" : list.toString()));
} catch (IOException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
올바르게 싱글 톤을 만들지 않으므로 아니오입니다. 'SingletonCls'인스턴스가 하나만 있다고 보장 할 수는 없습니다. 싱글 톤을 위해서 자바에서'enum'을 사용하십시오. –
'SingletonCls # getInstance' 메쏘드는 쓰레드에 안전하지 않습니다. 'singletonInstance'를 게으른 로딩 대신 처음부터 초기화하는 것이 더 낫습니다. –
@Yoonyou Ryu - Brain과 Luiggi가 지적했듯이, 이것은 스레드 안전하지 않으며 더 나은 접근법이 있습니다. 이를 수행하는 다른 방법은 http://stackoverflow.com/questions/3635396/pattern-for-lazy-thread-safe-singleton-instantiation-in-java를 참조하십시오. – lreeder