⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 weakhashmap.java

📁 this gcc-g++-3.3.1.tar.gz is a source file of gcc, you can learn more about gcc through this codes f
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* WeakHashMap -- a hashtable that keeps only weak references   to its keys, allowing the virtual machine to reclaim them   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.This file is part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; see the file COPYING.  If not, write to theFree Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307 USA.Linking this library statically or dynamically with other modules ismaking a combined work based on this library.  Thus, the terms andconditions of the GNU General Public License cover the wholecombination.As a special exception, the copyright holders of this library give youpermission to link this library with independent modules to produce anexecutable, regardless of the license terms of these independentmodules, and to copy and distribute the resulting executable underterms of your choice, provided that you also meet, for each linkedindependent module, the terms and conditions of the license of thatmodule.  An independent module is a module which is not derived fromor based on this library.  If you modify this library, you may extendthis exception to your version of the library, but you are notobligated to do so.  If you do not wish to do so, delete thisexception statement from your version. */package java.util;import java.lang.ref.WeakReference;import java.lang.ref.ReferenceQueue;/** * A weak hash map has only weak references to the key. This means that it * allows the key to be garbage collected if it is not used otherwise. If * this happens, the entry will eventually disappear from the map, * asynchronously. * * <p>A weak hash map makes most sense when the keys doesn't override the * <code>equals</code> method: If there is no other reference to the * key nobody can ever look up the key in this table and so the entry * can be removed.  This table also works when the <code>equals</code> * method is overloaded, such as String keys, but you should be prepared * to deal with some entries disappearing spontaneously. * * <p>Other strange behaviors to be aware of: The size of this map may * spontaneously shrink (even if you use a synchronized map and synchronize * it); it behaves as if another thread removes entries from this table * without synchronization.  The entry set returned by <code>entrySet</code> * has similar phenomenons: The size may spontaneously shrink, or an * entry, that was in the set before, suddenly disappears. * * <p>A weak hash map is not meant for caches; use a normal map, with * soft references as values instead, or try {@link LinkedHashMap}. * * <p>The weak hash map supports null values and null keys.  The null key * is never deleted from the map (except explictly of course). The * performance of the methods are similar to that of a hash map. * * <p>The value objects are strongly referenced by this table.  So if a * value object maintains a strong reference to the key (either direct * or indirect) the key will never be removed from this map.  According * to Sun, this problem may be fixed in a future release.  It is not * possible to do it with the jdk 1.2 reference model, though. * * @author Jochen Hoenicke * @author Eric Blake (ebb9@email.byu.edu) * * @see HashMap * @see WeakReference * @see LinkedHashMap * @since 1.2 * @status updated to 1.4 */public class WeakHashMap extends AbstractMap implements Map{  // WARNING: WeakHashMap is a CORE class in the bootstrap cycle. See the  // comments in vm/reference/java/lang/Runtime for implications of this fact.  /**   * The default capacity for an instance of HashMap.   * Sun's documentation mildly suggests that this (11) is the correct   * value.   */  private static final int DEFAULT_CAPACITY = 11;  /**   * The default load factor of a HashMap.   */  private static final float DEFAULT_LOAD_FACTOR = 0.75F;  /**   * This is used instead of the key value <i>null</i>.  It is needed   * to distinguish between an null key and a removed key.   */  // Package visible for use by nested classes.  static final Object NULL_KEY = new Object()  {    /**     * Sets the hashCode to 0, since that's what null would map to.     * @return the hash code 0     */    public int hashCode()    {      return 0;    }    /**     * Compares this key to the given object. Normally, an object should     * NEVER compare equal to null, but since we don't publicize NULL_VALUE,     * it saves bytecode to do so here.     * @return true iff o is this or null     */    public boolean equals(Object o)    {      return null == o || this == o;    }  };  /**   * The reference queue where our buckets (which are WeakReferences) are   * registered to.   */  private final ReferenceQueue queue;  /**   * The number of entries in this hash map.   */  // Package visible for use by nested classes.  int size;  /**   * The load factor of this WeakHashMap.  This is the maximum ratio of   * size versus number of buckets.  If size grows the number of buckets   * must grow, too.   */  private float loadFactor;  /**   * The rounded product of the capacity (i.e. number of buckets) and   * the load factor. When the number of elements exceeds the   * threshold, the HashMap calls <code>rehash()</code>.   */  private int threshold;  /**   * The number of structural modifications.  This is used by   * iterators, to see if they should fail.  This doesn't count   * the silent key removals, when a weak reference is cleared   * by the garbage collection.  Instead the iterators must make   * sure to have strong references to the entries they rely on.   */  // Package visible for use by nested classes.  int modCount;  /**   * The entry set.  There is only one instance per hashmap, namely   * theEntrySet.  Note that the entry set may silently shrink, just   * like the WeakHashMap.   */  private final class WeakEntrySet extends AbstractSet  {    /**     * Non-private constructor to reduce bytecode emitted.     */    WeakEntrySet()    {    }    /**     * Returns the size of this set.     *     * @return the set size     */    public int size()    {      return size;    }    /**     * Returns an iterator for all entries.     *     * @return an Entry iterator     */    public Iterator iterator()    {      return new Iterator()      {        /**         * The entry that was returned by the last         * <code>next()</code> call.  This is also the entry whose         * bucket should be removed by the <code>remove</code> call. <br>         *         * It is null, if the <code>next</code> method wasn't         * called yet, or if the entry was already removed.  <br>         *         * Remembering this entry here will also prevent it from         * being removed under us, since the entry strongly refers         * to the key.         */        WeakBucket.WeakEntry lastEntry;        /**         * The entry that will be returned by the next         * <code>next()</code> call.  It is <code>null</code> if there         * is no further entry. <br>         *         * Remembering this entry here will also prevent it from         * being removed under us, since the entry strongly refers         * to the key.         */        WeakBucket.WeakEntry nextEntry = findNext(null);        /**         * The known number of modification to the list, if it differs         * from the real number, we throw an exception.         */        int knownMod = modCount;        /**         * Check the known number of modification to the number of         * modifications of the table.  If it differs from the real         * number, we throw an exception.         * @throws ConcurrentModificationException if the number         *         of modifications doesn't match.         */        private void checkMod()        {          // This method will get inlined.          cleanQueue();          if (knownMod != modCount)            throw new ConcurrentModificationException();        }        /**         * Get a strong reference to the next entry after         * lastBucket.         * @param lastEntry the previous bucket, or null if we should         * get the first entry.         * @return the next entry.         */        private WeakBucket.WeakEntry findNext(WeakBucket.WeakEntry lastEntry)        {          int slot;          WeakBucket nextBucket;          if (lastEntry != null)            {              nextBucket = lastEntry.getBucket().next;              slot = lastEntry.getBucket().slot;            }          else            {              nextBucket = buckets[0];              slot = 0;            }          while (true)            {              while (nextBucket != null)                {                  WeakBucket.WeakEntry entry = nextBucket.getEntry();                  if (entry != null)                    // This is the next entry.                    return entry;                  // Entry was cleared, try next.                  nextBucket = nextBucket.next;                }              slot++;              if (slot == buckets.length)                // No more buckets, we are through.                return null;              nextBucket = buckets[slot];            }        }        /**         * Checks if there are more entries.         * @return true, iff there are more elements.         * @throws ConcurrentModificationException if the hash map was         *         modified.         */        public boolean hasNext()        {          checkMod();          return nextEntry != null;        }        /**         * Returns the next entry.         * @return the next entry.         * @throws ConcurrentModificationException if the hash map was         *         modified.         * @throws NoSuchElementException if there is no entry.         */        public Object next()        {          checkMod();          if (nextEntry == null)            throw new NoSuchElementException();          lastEntry = nextEntry;          nextEntry = findNext(lastEntry);          return lastEntry;        }        /**         * Removes the last returned entry from this set.  This will         * also remove the bucket of the underlying weak hash map.         * @throws ConcurrentModificationException if the hash map was         *         modified.         * @throws IllegalStateException if <code>next()</code> was         *         never called or the element was already removed.         */        public void remove()        {          checkMod();          if (lastEntry == null)            throw new IllegalStateException();          modCount++;          internalRemove(lastEntry.getBucket());          lastEntry = null;          knownMod++;        }      };    }  }  /**   * A bucket is a weak reference to the key, that contains a strong   * reference to the value, a pointer to the next bucket and its slot   * number. <br>   *   * It would be cleaner to have a WeakReference as field, instead of   * extending it, but if a weak reference gets cleared, we only get   * the weak reference (by queue.poll) and wouldn't know where to   * look for this reference in the hashtable, to remove that entry.   *   * @author Jochen Hoenicke   */  private static class WeakBucket extends WeakReference  {    /**     * The value of this entry.  The key is stored in the weak     * reference that we extend.     */    Object value;    /**     * The next bucket describing another entry that uses the same     * slot.     */    WeakBucket next;    /**     * The slot of this entry. This should be     * <code>Math.abs(key.hashCode() % buckets.length)</code>.     *     * But since the key may be silently removed we have to remember     * the slot number.     *     * If this bucket was removed the slot is -1.  This marker will     * prevent the bucket from being removed twice.     */    int slot;    /**     * Creates a new bucket for the given key/value pair and the specified     * slot.     * @param key the key     * @param queue the queue the weak reference belongs to     * @param value the value     * @param slot the slot.  This must match the slot where this bucket     *        will be enqueued.     */    public WeakBucket(Object key, ReferenceQueue queue, Object value,                      int slot)    {      super(key, queue);      this.value = value;      this.slot = slot;    }    /**     * This class gives the <code>Entry</code> representation of the     * current bucket.  It also keeps a strong reference to the     * key; bad things may happen otherwise.     */    class WeakEntry implements Map.Entry    {      /**       * The strong ref to the key.       */      Object key;      /**       * Creates a new entry for the key.       * @param key the key       */      public WeakEntry(Object key)      {        this.key = key;      }      /**       * Returns the underlying bucket.       * @return the owning bucket       */      public WeakBucket getBucket()      {        return WeakBucket.this;      }      /**       * Returns the key.       * @return the key       */      public Object getKey()      {        return key == NULL_KEY ? null : key;      }      /**       * Returns the value.       * @return the value       */      public Object getValue()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -