【发布时间】:2017-11-30 17:23:14
【问题描述】:
目标 - 使用 sax 解析器并行解析不同的 xml 文件 多个线程。
找到多个与同一主题相关的帖子。但他们都没有指出答案。
我知道 SAXParserFactory 和 SAXParser 不是线程安全的。根据我的研究,我需要为每个线程创建 SAXParserFactory 和 SAXParser 的新实例。 我怎样才能做到这一点。 (也是 MySAXHandler 的新实例)
请找到我的代码的当前实现。
SAXParser 的启动
@Override
public GameStatisticsDTO processStatsGameStatXML(File gameStatsStatFile) {
try(InputStream inputStream = new FileInputStream(gameStatsStatFile)) {
// New Handler instance
GameStatsSAXHandler gameStatsSAXHandler = new GameStatsSAXHandler();
Reader reader = new InputStreamReader(inputStream, Constants.ENCODING_TYPE_UTF_8);
InputSource inputSource = new InputSource(reader);
inputSource.setEncoding(Constants.ENCODING_TYPE_UTF_8);
// New Instance of SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
// New Instance of SAXParser
SAXParser saxParser = factory.newSAXParser();
// Create an XML reader to set the entity resolver.
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setEntityResolver(new StatsCustomResolver());
xmlReader.setContentHandler(gameStatsSAXHandler);
xmlReader.parse(inputSource);
return gameStatsSAXHandler.getGameStatisticsDTO();
} catch (Exception e) {
throw new UnprocessableEntityException();
}
}
这将调用 GameStatsSAXHandler 来解析 xml 节点。 Within that class I'm maintaining Instance reference variables to store my parsed data.
public class GameStatsSAXHandler extends DefaultHandler {
// Instance Reference Variable - Hope this is thread safe
private GameStatisticsDTO gameStatisticsDTO = new GameStatisticsDTO();
protected GameStatisticsDTO getGameStatisticsDTO() {
return this.gameStatisticsDTO;
}
@Override
public void startElement (String uri, String localName, String
elementName, Attributes attributes) throws SAXException {
// Process the data and add it to the gameStatisticsDTO
}
@Override
public void endElement (String uri, String localName, String
elementName) throws SAXException {
// Do some processing in gameStatisticsDTO
}
}
gameStatisticsDTO 包含多个实例引用变量(对象和列表)
所以我有 2 个问题。
1) 因为只有局部原始变量是线程安全的。这是 GameStatsSAXHandler 及其 GameStatisticsDTO 是线程安全的?
我的想法:如果我为每个线程创建新的 GameStatsSAXHandler 实例,那么 GameStatisticsDTO 将是线程安全的。
2) 如何将其转换为多线程环境 并行性。
我的想法:创建 ThreadPoolExecutor 并传递新的 SAXParserFactory 并生成新的 SAXParser 并创建新的 GameStatsSAXHandler 并将其传递给基方法进行处理。 (processStatsGameStatXML 方法)
但是我怎样才能为每个线程创建新的实例呢?代码示例会很棒! 谢谢
【问题讨论】:
-
首先需要多线程吗? SAX 也是正确的解析模型吗?
标签: java xml multithreading parallel-processing saxparser