Я работаю над программой, которая должна загружать одну и ту же информацию из файлов опций в несколько потоков.Поэтому я сделал простое представление класса каждого файла на основе абстрактной модели: (показан ниже 1 пример многих из этих классов)
package OptionManager;
import java.util.Properties;
public class EngineOptions extends AbstractOptions{
//values
private static String debugEnabled;
private static String debugAvgLoadtime;
private static String showShaderUsed;
private static String mainLanguage;
//keys
public static final String DEBUGENABLED_KEY = "debugEnabled";
public static final String DEBUGAVGLOADTIME_KEY = "debugAvgLoadtime";
public static final String SHOWSHADERUSED_KEY = "showShaderUsed";
public static final String MAINLANGUAGE_KEY = "mainLanguage";
public static String getProperty(String key) {
return properties.getProperty(key);
}
public static void loadFromFile(String filename) {
OptionReader loader = new OptionReader(filename);
//load properties
debugEnabled = loader.getProperty(DEBUGENABLED_KEY);
debugAvgLoadtime = loader.getProperty(DEBUGAVGLOADTIME_KEY);
showShaderUsed = loader.getProperty(SHOWSHADERUSED_KEY);
mainLanguage = loader.getProperty(MAINLANGUAGE_KEY);
properties.put(DEBUGENABLED_KEY, debugEnabled);
properties.put(DEBUGAVGLOADTIME_KEY, debugAvgLoadtime);
properties.put(SHOWSHADERUSED_KEY, showShaderUsed);
properties.put(MAINLANGUAGE_KEY, mainLanguage);
}
}
Вот абстрактный класс, который он использует:
package OptionManager;
import java.util.Properties;
public abstract class AbstractOptions {
protected static volatile Properties properties;
public static void setupProperties() {
properties = new Properties();
}
public static void setupProperties(Properties properties) {}
public static void setProperty(String key, String value) {
if(properties.getProperty(key) == null) {
//throw exception.
}
properties.setProperty(key, value);
}
public static String getProperty(String key) {
System.out.println(properties);
return properties.getProperty(key);
}
//public static void loadFromFile(String filename) {}
}
Я могу загрузить файлы опций в главном потоке (созданном JVM для запуска программы) и использовать эту систему в этом потоке, чтобы получить все нужные мне опции.Фактически, в качестве теста я печатаю весь список параметров в классе EngineOptions каждый раз, когда получаю доступ к параметру, который выдает следующий результат (при получении параметра mainLanguage):
{mainLanguage = language_IT, debugAvgLoadtime = 1, debugEnabled = 1, showShaderUsed = 1} language_IT
Однако, когда я пытаюсь получить доступ к той же опции внутри другого потока (созданного основным потоком и запущенного после того, как я напечатал вывод выше), я получаю это:
{} null
Это наводит меня на мысль, что для каждого потока значения моих статических полей не являются общими.Поэтому я нашел этот ответ , в котором предлагалось использовать «volatile» для решения проблемы.Однако это не сработало.
Другой вариант - загружать файлы опций в каждом потоке, но я бы не хотел этого делать, потому что причиной, по которой мне пришлось загружать файлы опций несколько раз для каждого потока, была причина, по которой я создалэта система в первую очередь.
Как я могу исправить эту проблему и поделиться значениями параметра для нескольких потоков?
РЕДАКТИРОВАТЬ:
Как создать новый параметрlist:
OptionHandler.addOptionFile(OptionHandler.ENGINE_OPTION_ID, new EngineOptions(), "EngineOptions");
OptionHandler.loadOptionListFromFile(OptionHandler.ENGINE_OPTION_ID, OptionHandler.ENGINE_OPTION_TYPE);
Как я вызываю опцию из потока:
String currentLang = OptionHandler.getProperty(EngineOptions.MAINLANGUAGE_KEY, OptionHandler.ENGINE_OPTION_ID);
System.out.println(currentLang);
EDIT 2:
package OptionManager;
import java.util.HashMap;
import java.util.Map;
public class OptionHandler {
private static HashMap<Integer, AbstractOptions> optionList;
private static HashMap<Integer, String> optionFilename;
//OptionFIleID's (Starting from 101 to 199)
public static final int GRAPHIC_OPTION_ID = 101;
public static final int ENGINE_OPTION_ID = 102;
public static final int CURRENT_LANGUAGE_ID = 103;
public static final int GRAPHIC_OPTION_TYPE = 201;
public static final int ENGINE_OPTION_TYPE = 202;
public static final int CURRENT_LANGUAGE_TYPE = 203;
public static void setupOptions() {
optionList = new HashMap<Integer, AbstractOptions>();
optionFilename = new HashMap<Integer, String>();
}
public static void addOptionFile(int id, AbstractOptions options, String filename) {
options.setupProperties();
optionList.put(id, options);
optionFilename.put(id, filename);
}
public static String getProperty(String optionKey, int optionFileID) {
return optionList.get(optionFileID).getProperty(optionKey);
}
public static void loadOptionListFromFile(int id, int type) {
System.out.println(optionFilename.get(id));
if(type == GRAPHIC_OPTION_TYPE)
GraphicOptions.loadFromFile(optionFilename.get(id));
if(type == ENGINE_OPTION_TYPE)
EngineOptions.loadFromFile(optionFilename.get(id));
if(type == CURRENT_LANGUAGE_TYPE)
CurrentLanguage.loadFromFile(optionFilename.get(id));
}
}