我有以下代码。
private static volatile Properties props = null;
private static volatile StanfordCoreNLP pipeline = null;
/**
*
* @return
*/
static {
if (props == null) {
props = new Properties();
props.setProperty("annotators", "tokenize, ssplit, parse, sentiment");
}
if (pipeline == null) {
pipeline = new StanfordCoreNLP(props);
}
}
我想在我的整个应用程序中有一个变量props
和pipeline
的单个实例,它是多线程的。
我的代码是对的还是我错过了什么?
感谢。
答案 0 :(得分:1)
可以通过使用方法调用来摆脱volatile
,并通过静态初始化保持线程安全。
private static final Properties props = initProperties();
private static Properties initProperties() {
Properties props = new Properties();
props.setProperty("annotators", "tokenize, ssplit, parse, sentiment");
return props;
}
public static Properties getProperties() {
return props;
}
编辑: 要回答你的问题,是的,OP中的代码确实是线程安全的,尽管我以前给出的是我个人做的方式。
答案 1 :(得分:0)
你的代码似乎正确,因为你在类加载时创建实例,所以你只需要为它们创建getter
但我建议在这种情况下使用单例模式,如下所示
我在多线程环境中使用了单锁模式和双重锁定
public class Utility{
private static final Object masterLock = new Object();
private static volatile Properties props = null;
private static volatile StanfordCoreNLP pipeline = null;
static Properties getPropertiesInstance(){
if(props == null){
synchronized (masterLock) {
if(props == null){
props = new Properties();
}
}
}
return props;
}
static StanfordCoreNLP getStanfordCoreNLPInstance(){
if(pipeline == null){
synchronized (masterLock) {
if(pipeline == null){
pipeline = new StanfordCoreNLP();
}
}
}
return pipeline;
}
}
答案 2 :(得分:0)
volatile
。 Java保证静态初始化正确同步。也不需要方法调用。另请参阅Are Java static initializers thread safe?和https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html