加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 哪种实现更好:基于WeakHashMap的缓存还是基于ThreadLoc

发布时间:2020-12-15 05:04:48 所属栏目:Java 来源:网络整理
导读:我很难在以下两个实现之间做出决定. 我想缓存每个线程的 javax.xml.parsers.DocumentBuilder对象.我主要担心的是运行时性能–Hench我很乐意避免使用尽可能多的GC.记忆不是问题. 我已经写了两个POC实现,很高兴听到社区PROS / CONS关于每个实现. 谢谢你的帮助.
我很难在以下两个实现之间做出决定.
我想缓存每个线程的 javax.xml.parsers.DocumentBuilder对象.我主要担心的是运行时性能–Hench我很乐意避免使用尽可能多的GC.记忆不是问题.

我已经写了两个POC实现,很高兴听到社区PROS / CONS关于每个实现.

谢谢你的帮助.

选项#1 – WeakHashMap

import java.io.IOException;
import java.io.StringReader;
import java.util.WeakHashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class DocumentBuilder_WeakHashMap {
    private static final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    private static final WeakHashMap<Thread,DocumentBuilder> CACHE = new WeakHashMap<Thread,DocumentBuilder>();

    public static Document documentFromXMLString(String xml) throws SAXException,IOException,ParserConfigurationException {
        DocumentBuilder builder = CACHE.get(Thread.currentThread());
        if(builder == null) {
            builder = factory.newDocumentBuilder();
            CACHE.put(Thread.currentThread(),builder);
        }

        return builder.parse(new InputSource(new StringReader(xml)));
    }

}

选项#2 – ThreadLocal

import java.io.IOException;
import java.io.StringReader;
import java.lang.ref.WeakReference;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class DocumentBuilder_ThreadLocal {
    private static final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    private static final ThreadLocal<WeakReference<DocumentBuilder>> CACHE = 
        new ThreadLocal<WeakReference<DocumentBuilder>>() {
            @Override 
            protected WeakReference<DocumentBuilder> initialValue() {
                try {
                    return new WeakReference<DocumentBuilder>(factory.newDocumentBuilder());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        };

    public static Document documentFromXMLString(String xml) throws ParserConfigurationException,SAXException,IOException {
        WeakReference<DocumentBuilder> builderWeakReference = CACHE.get();
        DocumentBuilder builder = builderWeakReference.get();

        if(builder == null) {
            builder = factory.newDocumentBuilder();
            CACHE.set(new WeakReference<DocumentBuilder>(builder));
        }

        return builder.parse(new InputSource(new StringReader(xml)));
    }
}

它们都做同样的事情(将documentFromXMLString()暴露给外部世界),你会使用哪一个?

谢谢,
格言.

解决方法

ThreadLocal解决方案更好,只要您不使用弱引用,而是直接使用ThreadLocal< DocumentBuilder>.
对ThreadLocal值的访问更快,因为线程直接引用包含所有ThreadLocal值的数组,并且它只需要计算此数组中的索引以进行查找.
查看ThreadLocal source,看看为什么索引计算速度很快(int index = hash& values.mask;)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读