请看下面的类,告诉我下面的代码是否是线程安全的。我的问题的关键是,一个类的static
方法和该方法调用单例实例的方法。另外,static
方法由Runnable
实例调用。所以我问你们看代码 - static
方法,它在多线程环境中调用单例方法 - 是否安全?单身和多线程
如果你回答我的问题,我将非常感激。
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'实例。在Java中对单例使用'enum' –
'SingletonCls#getInstance'方法不是线程安全的。最好从头开始初始化'singletonInstance',而不是延迟加载它。 –
@Yonyou Ryu - As Brain和Luiggi表示,这不是线程安全的,有更好的方法。请参阅http://stackoverflow.com/questions/3635396/pattern-for-lazy-thread-safe-singleton-instantiation-in-java其他方式来做到这一点。 – lreeder