【问题标题】:Why is WeakReferenced object not removed by WeakHashMap为什么 WeakHashMap 没有删除 WeakReferenced 对象
【发布时间】:2014-07-24 11:02:37
【问题描述】:

我最近尝试了解 java.util.WeakHashMap。

但是当我使用 Wea​​kReference 包装一个字符串时,WeakHash 并没有最终确定条目。

另请注意,我在主线程中清除 WeakReference,然后在线程方法中引用它。

执行时,while 循环不会中断!

public class WeakHashMapTotorial
{
    private static Map<String, String> map;

    public static void main(String args[])
    {
        WeakReference<String> s = new WeakReference<String>("Maine");
        map = new WeakHashMap<>();
        map.put(s.get(), "Augusta");

        Runnable runner = new Runnable()
        {
            public void run()
            {
                while (map.containsKey("Maine"))
                {
                    try
                    {
                        Thread.sleep(1000);
                    } catch (InterruptedException ignored)
                    {}
                    System.out.println("Thread waiting");
                    System.gc();
                }
            }
        };
        Thread t = new Thread(runner);
        t.start();
        System.out.println("Main waiting");
        try
        {
            t.join();
        } catch (InterruptedException ignored)
        {}
        s.clear();

    }
}

【问题讨论】:

    标签: java collections weakhashmap


    【解决方案1】:

    WeakReference 包裹在字符串常量周围是行不通的。字符串常量是实习的,这意味着引用永远不会消失。此外,您的代码在您的 run 方法中保留对相同常量的引用,进一步保证了强引用。

    【讨论】:

    • 字符串常量是总是被实习的。这是 JLS 要求的。
    【解决方案2】:

    您正在使用的字符串由实习字符串池保存,请尝试以下操作:

        WeakReference<String> s = new WeakReference<String>(new String("Maine"));
        map = new WeakHashMap<>();
        map.put(s.get(), "Augusta");
    

    这种实习效果在Java Language Spec中有描述

    此外,字符串字面量总是指向同一个类的实例 细绳。这是因为字符串文字 - 或者更一般地说,字符串 这是常量表达式的值(第 15.28 节) - 是“interned” 以便共享唯一实例,使用方法 String.intern。

    【讨论】:

    • 谢谢克里斯。我现在得到了丢失的部分:)
    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 2012-02-17
    相关资源
    最近更新 更多