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

📄 concurrentreaderhashmap.java

📁 采用JAVA开发
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
          first = new Entry(e.hash, e.key, e.value, first);
        ttab[i] = first;
      }

      return t;
    } 
    catch (CloneNotSupportedException e) { 
      // this shouldn't happen, since we are Cloneable
      throw new InternalError();
    }
  }

  // Views

  protected transient Set keySet = null;
  protected transient Set entrySet = null;
  protected transient Collection values = null;

  /**
   * Returns a set view of the keys contained in this map.  The set is
   * backed by the map, so changes to the map are reflected in the set, and
   * vice-versa.  The set supports element removal, which removes the
   * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
   * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
   * <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
   * <tt>addAll</tt> operations.
   *
   * @return a set view of the keys contained in this map.
   */
  
  public Set keySet() {
    Set ks = keySet;
    return (ks != null)? ks : (keySet = new KeySet());
  }
  
  private class KeySet extends AbstractSet {
    public Iterator iterator() {
      return new KeyIterator();
    }
    public int size() {
      return ConcurrentReaderHashMap.this.size();
    }
    public boolean contains(Object o) {
      return ConcurrentReaderHashMap.this.containsKey(o);
    }
    public boolean remove(Object o) {
      return ConcurrentReaderHashMap.this.remove(o) != null;
    }
    public void clear() {
      ConcurrentReaderHashMap.this.clear();
    }
  }

  /**
   * Returns a collection view of the values contained in this map.  The
   * collection is backed by the map, so changes to the map are reflected in
   * the collection, and vice-versa.  The collection supports element
   * removal, which removes the corresponding mapping from this map, via the
   * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
   * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
   * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
   *
   * @return a collection view of the values contained in this map.
   */
  
  public Collection values() {
    Collection vs = values;
    return (vs != null)? vs : (values = new Values());
  }
  
  private class Values extends AbstractCollection {
    public Iterator iterator() {
      return new ValueIterator();
    }
    public int size() {
      return ConcurrentReaderHashMap.this.size();
    }
    public boolean contains(Object o) {
      return ConcurrentReaderHashMap.this.containsValue(o);
    }
    public void clear() {
      ConcurrentReaderHashMap.this.clear();
    }
  }

  /**
   * Returns a collection view of the mappings contained in this map.  Each
   * element in the returned collection is a <tt>Map.Entry</tt>.  The
   * collection is backed by the map, so changes to the map are reflected in
   * the collection, and vice-versa.  The collection supports element
   * removal, which removes the corresponding mapping from the map, via the
   * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
   * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
   * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
   *
   * @return a collection view of the mappings contained in this map.
   */
  
  public Set entrySet() {
    Set es = entrySet;
    return (es != null) ? es : (entrySet = new EntrySet());
  }

  private class EntrySet extends AbstractSet {
    public Iterator iterator() {
      return new HashIterator();
    }
    public boolean contains(Object o) {
      if (!(o instanceof Map.Entry))
        return false;
      Map.Entry entry = (Map.Entry)o;
      Object v = ConcurrentReaderHashMap.this.get(entry.getKey());
      return v != null && v.equals(entry.getValue());
    }
    public boolean remove(Object o) {
      if (!(o instanceof Map.Entry))
        return false;
      return ConcurrentReaderHashMap.this.findAndRemoveEntry((Map.Entry)o);
    }
    public int size() {
      return ConcurrentReaderHashMap.this.size();
    }
    public void clear() {
      ConcurrentReaderHashMap.this.clear();
    }
  }

  /**
   * Helper method for entrySet.remove
   **/
  protected synchronized boolean findAndRemoveEntry(Map.Entry entry) {
    Object key = entry.getKey();
    Object v = get(key);
    if (v != null && v.equals(entry.getValue())) {
      remove(key);
      return true;
    }
    else
      return false;
  }

  /**
   * Returns an enumeration of the keys in this table.
   *
   * @return  an enumeration of the keys in this table.
   * @see     Enumeration
   * @see     #elements()
   * @see	#keySet()
   * @see	Map
   */
  public Enumeration keys() {
    return new KeyIterator();
  }

  /**
   * Returns an enumeration of the values in this table.
   * Use the Enumeration methods on the returned object to fetch the elements
   * sequentially.
   *
   * @return  an enumeration of the values in this table.
   * @see     java.util.Enumeration
   * @see     #keys()
   * @see	#values()
   * @see	Map
   */
  
  public Enumeration elements() {
    return new ValueIterator();
  }


  /**
   * ConcurrentReaderHashMap collision list entry.
   */

  protected static class Entry implements Map.Entry {

    /* 
       The use of volatile for value field ensures that
       we can detect status changes without synchronization.
       The other fields are never changed, and are
       marked as final. 
    */

    protected final int hash;
    protected final Object key;
    protected final Entry next;
    protected volatile Object value;

    Entry(int hash, Object key, Object value, Entry next) {
      this.hash = hash;
      this.key = key;
      this.next = next;
      this.value = value;
    }

    // Map.Entry Ops 

    public Object getKey() {
      return key;
    }

    /**
     * Get the value.  Note: In an entrySet or entrySet.iterator,
     * unless the set or iterator is used under synchronization of the
     * table as a whole (or you can otherwise guarantee lack of
     * concurrent modification), <tt>getValue</tt> <em>might</em>
     * return null, reflecting the fact that the entry has been
     * concurrently removed. However, there are no assurances that
     * concurrent removals will be reflected using this method.
     * 
     * @return     the current value, or null if the entry has been 
     * detectably removed.
     **/
    public Object getValue() {
      return value; 
    }

    /**
     * Set the value of this entry.  Note: In an entrySet or
     * entrySet.iterator), unless the set or iterator is used under
     * synchronization of the table as a whole (or you can otherwise
     * guarantee lack of concurrent modification), <tt>setValue</tt>
     * is not strictly guaranteed to actually replace the value field
     * obtained via the <tt>get</tt> operation of the underlying hash
     * table in multithreaded applications.  If iterator-wide
     * synchronization is not used, and any other concurrent
     * <tt>put</tt> or <tt>remove</tt> operations occur, sometimes
     * even to <em>other</em> entries, then this change is not
     * guaranteed to be reflected in the hash table. (It might, or it
     * might not. There are no assurances either way.)
     *
     * @param      value   the new value.
     * @return     the previous value, or null if entry has been detectably
     * removed.
     * @exception  NullPointerException  if the value is <code>null</code>.
     * 
     **/

    public Object setValue(Object value) {
      if (value == null)
        throw new NullPointerException();
      Object oldValue = this.value;
      this.value = value;
      return oldValue;
    }

    public boolean equals(Object o) {
      if (!(o instanceof Map.Entry))
        return false;
      Map.Entry e = (Map.Entry)o;
      return (key.equals(e.getKey()) && value.equals(e.getValue()));
    }
    
    public int hashCode() {
      return  key.hashCode() ^ value.hashCode();
    }
    
    public String toString() {
      return key + "=" + value;
    }

  }

  protected class HashIterator implements Iterator, Enumeration {
    protected final Entry[] tab;           // snapshot of table
    protected int index;                   // current slot 
    protected Entry entry = null;          // current node of slot
    protected Object currentKey;           // key for current node
    protected Object currentValue;         // value for current node
    protected Entry lastReturned = null;   // last node returned by next

    protected HashIterator() {
      tab = ConcurrentReaderHashMap.this.getTableForReading();
      index = tab.length - 1;
    }

    public boolean hasMoreElements() { return hasNext(); }
    public Object nextElement() { return next(); }


    public boolean hasNext() {

      /*
        currentkey and currentValue are set here to ensure that next()
        returns normally if hasNext() returns true. This avoids
        surprises especially when final element is removed during
        traversal -- instead, we just ignore the removal during
        current traversal.  
      */

      for (;;) {
        if (entry != null) {
          Object v = entry.value;
          if (v != null) {
            currentKey = entry.key;
            currentValue = v;
            return true;
          }
          else
            entry = entry.next;
        }

        while (entry == null && index >= 0)
          entry = tab[index--];

        if (entry == null) {
          currentKey = currentValue = null;
          return false;
        }
      }
    }

    protected Object returnValueOfNext() { return entry; }

    public Object next() {
      if (currentKey == null && !hasNext())
        throw new NoSuchElementException();

      Object result = returnValueOfNext();
      lastReturned = entry;
      currentKey = currentValue = null;
      entry = entry.next;
      return result;
    }

    public void remove() {
      if (lastReturned == null)
        throw new IllegalStateException();
      ConcurrentReaderHashMap.this.remove(lastReturned.key);
      lastReturned = null;
    }

  }


  protected class KeyIterator extends HashIterator {
    protected Object returnValueOfNext() { return currentKey; }
  }
  
  protected class ValueIterator extends HashIterator {
    protected Object returnValueOfNext() { return currentValue; }
  }
  


  /**
   * Save the state of the <tt>ConcurrentReaderHashMap</tt> 
   * instance to a stream (i.e.,
   * serialize it).
   *
   * @serialData The <i>capacity</i> of the 
   * ConcurrentReaderHashMap (the length of the
   * bucket array) is emitted (int), followed  by the
   * <i>size</i> of the ConcurrentReaderHashMap (the number of key-value
   * mappings), followed by the key (Object) and value (Object)
   * for each key-value mapping represented by the ConcurrentReaderHashMap
   * The key-value mappings are emitted in no particular order.
   */

  private synchronized void writeObject(java.io.ObjectOutputStream s)
    throws IOException  {
    // Write out the threshold, loadfactor, and any hidden stuff
    s.defaultWriteObject();
    
    // Write out number of buckets
    s.writeInt(table.length);
    
    // Write out size (number of Mappings)
    s.writeInt(count);
    
    // Write out keys and values (alternating)
    for (int index = table.length-1; index >= 0; index--) {
      Entry entry = table[index];
      
      while (entry != null) {
        s.writeObject(entry.key);
        s.writeObject(entry.value);
        entry = entry.next;
      }
    }
  }

  /**
   * Reconstitute the <tt>ConcurrentReaderHashMap</tt> 
   * instance from a stream (i.e.,
   * deserialize it).
   */
  private synchronized void readObject(java.io.ObjectInputStream s)
    throws IOException, ClassNotFoundException  {
    // Read in the threshold, loadfactor, and any hidden stuff
    s.defaultReadObject();

    // Read in number of buckets and allocate the bucket array;
    int numBuckets = s.readInt();
    table = new Entry[numBuckets];
    
    // Read in size (number of Mappings)
    int size = s.readInt();
    
    // Read the keys and values, and put the mappings in the table
    for (int i=0; i<size; i++) {
      Object key = s.readObject();
      Object value = s.readObject();
      put(key, value);
    }
  }
  
  /** 
   * Return the number of slots in this table 
   **/

  public synchronized int capacity() {
    return table.length;
  }

  /** 
   * Return the load factor 
   **/
  public float loadFactor() {
    return loadFactor;
  }
}

⌨️ 快捷键说明

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