单例线程安全SAX解析器实例

时间:2016-09-23 10:13:45

标签: java multithreading singleton sax

我想创建一个线程安全的SAX解析器的单例实例。

但我无法使用随需应变的习惯用法,因为SAX解析器会抛出SAXException,如果它是一个类变量则无法处理。这是我写的代码。

public class Parser {
    private static SAXParser parser;
    Parser() throws ParserConfigurationException, SAXException {
    if (parser==null)
        parser=LazyHolder.factory.newSAXParser();
    }
    private static class LazyHolder {
        private static final SAXParserFactory factory=SAXParserFactory.newInstance();
        }
    public SAXParser getInstance() {
        return parser;
    }
}

有没有更好的方法来实现它?

1 个答案:

答案 0 :(得分:1)

  

但我无法使用随需应变的习惯用法,因为SAX解析器会抛出SAXException,如果它是一个类变量则无法处理。

如果这只是在初始化期间绕过异常,你可以通过执行以下操作来解决这个问题:

 public class Wrapper {
     private static MyClassThatThrows singleton;
     static {
         try {
             singleton = new MyClassThatThrows();
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }
     ...
     public static MyClassThatThrows getInstance() {
        return singleton;
     }
}

如果解析器抛出,停止加载类。

但是,SAXParserFactorySAXParser都不是线程安全的,因此您可以改为使用ThreadLocal为每个线程生成一个。

public class Parser {
    private final ThreadLocal<SAXParserFactory> factoryThreadLocal = new ThreadLocal<>() {
         public SAXParserFactory initialValue() {
             try {
                 return SAXParserFactory.newInstance();
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
         }
    };
    public SAXParser getInstance() {
        // you could catch and re-throw the RuntimeException if the caller should handle it
        return factoryThreadLocal.get().newInstance();
    }
}