03 String#intern

2020-11-19  本文已影响0人  格林哈

1 String

2 案例

public class StringTest2 {
    public static void main(String[] args) {
        String s = new String("111");
        s.intern();
        String s2 = "111";
        System.out.println(s == s2);

        String s3 = new String("1") + new String("1");
        s3.intern();
        String s4 = "11";
        System.out.println(s3 == s4);

        char[] strs = {'a','b'};
        String s5 = new String(strs,0,2);
        s5.intern();
        String s6 = "ab";
        System.out.println(s5 == s6);

    }
}

// 输出
false
true
true

3 Eureka StringCache

/**
 * An alternative to {@link String#intern()} with no capacity constraints.
 *  String#intern() 的替代选择,没有容量限制。
 *
 * @author Tomasz Bak
 */
public class StringCache {

    public static final int LENGTH_LIMIT = 38;

    private static final StringCache INSTANCE = new StringCache();

    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    //key 不存在 强引用,下次gc 直接回收
    private final Map<String, WeakReference<String>> cache = new WeakHashMap<String, WeakReference<String>>();
    private final int lengthLimit;

    public StringCache() {
        this(LENGTH_LIMIT);
    }

    public StringCache(int lengthLimit) {
        this.lengthLimit = lengthLimit;
    }

    public String cachedValueOf(final String str) {
        if (str != null && (lengthLimit < 0 || str.length() <= lengthLimit)) {
            // Return value from cache if available 从缓存返回值(如果有)
            try {
                lock.readLock().lock();
                WeakReference<String> ref = cache.get(str);
                if (ref != null) {
                    return ref.get();
                }
            } finally {
                lock.readLock().unlock();
            }

            // Update cache with new content 用新内容更新缓存
            try {
                lock.writeLock().lock();
                WeakReference<String> ref = cache.get(str);
                if (ref != null) {
                    return ref.get();
                }
                cache.put(str, new WeakReference<>(str));
            } finally {
                lock.writeLock().unlock();
            }
            return str;
        }
        return str;
    }

    public int size() {
        try {
            lock.readLock().lock();
            return cache.size();
        } finally {
            lock.readLock().unlock();
        }
    }

    public static String intern(String original) {
        return INSTANCE.cachedValueOf(original);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读