为什么WeakHashMap不会删除WeakReferenced对象

时间:2014-07-24 11:02:38

标签: java collections weakhashmap

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

但是当我使用WeakReference来包装一个String时,WeakHash并没有最终确定Entry。

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

执行时,循环根本不会破坏!

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();

    }
}

2 个答案:

答案 0 :(得分:2)

围绕String常量包裹WeakReference将不起作用。字符串常量被实现,这意味着引用永远不会消失。此外,您的代码在run方法中保留对同一常量的引用,进一步保证了强引用仍然存在。

答案 1 :(得分:1)

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

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

这种实习效果在Java Language Spec

中有所描述
  

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