[concurrency-interest] Reference Collections

Nathan Reynolds nathan.reynolds at oracle.com
Thu Jan 5 18:45:38 EST 2012


Does using a referrer instead of a reference make any difference?  As 
long as the reference is garbage by the time GC starts then GC won't 
have to deal with it.  It won't have to track that there is a soft/weak 
link to an object because the Reference is garbage.

Nathan Reynolds 
<http://psr.us.oracle.com/wiki/index.php/User:Nathan_Reynolds> | 
Consulting Member of Technical Staff | 602.333.9091
Oracle PSR Engineering <http://psr.us.oracle.com/> | Server Technology

On 1/5/2012 4:17 PM, Peter Firmstone wrote:
> Just thought I'd better clarify how reads are performed, the Referrer
> interface exists to avoid creating unnecessary references, it defines
> the equals and hashCode contracts all reference implementations must
> follow.
>
> /*
>   * Licensed to the Apache Software Foundation (ASF) under one
>   * or more contributor license agreements.  See the NOTICE file
>   * distributed with this work for additional information
>   * regarding copyright ownership. The ASF licenses this file
>   * to you under the Apache License, Version 2.0 (the
>   * "License"); you may not use this file except in compliance
>   * with the License. You may obtain a copy of the License at
>   *
>   *      http://www.apache.org/licenses/LICENSE-2.0
>   *
>   * Unless required by applicable law or agreed to in writing, software
>   * distributed under the License is distributed on an "AS IS" BASIS,
>   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
>   * See the License for the specific language governing permissions and
>   * limitations under the License.
>   */
>
> package org.apache.river.impl.util;
>
> import java.lang.ref.Reference;
>
> /**
>   * An interface for References used in collections, it defines the
> equals
>   * and hashCode contracts as well as methods identical to Reference.
>   *
>   * A client may wish to implement this interface to replace a standard
> Referrer
>   * during serialisation with custom implementations to deconstruct and
>   * reconstruct non serialisable objects, or to perform integrity checks.
>   *
>   * This must be implemented in a Collection provided by the client.
>   *
>   * After de-serialisation is complete, the client Referrer will be
> replaced
>   * with a standard Referrer.
>   *
>   * @see Reference
>   * @see Ref
>   * @param<T>
>   * @author Peter Firmstone
>   */
> public interface Referrer<T>  {
>
>      /**
>       * @see Reference#get()
>       */
>      public T get() ;
>      /**
>       * @see Reference#clear()
>       */
>      public void clear();
>      /**
>       * @see Reference#isEnqueued()
>       * @return true if enqueued.
>       */
>      public boolean isEnqueued();
>      /**
>       * @see Reference#enqueue()
>       * @return
>       */
>      public boolean enqueue();
>
>      /**
>       * Equals is calculated on IDENTITY or equality.
>       *
>       * IDENTITY calculation:
>       *
>       * if (this == o) return true;
>       * if (!(o instanceof Referrer)) return false;
>       * Object k1 = get();
>       * Object k2 = ((Referrer) o).get();
>       * if ( k1 != null&&  k1 == k2 ) return true;
>       * return ( k1 == null&&  k2 == null&&  hashCode() == o.hashCode());
>       *
>       * Equality calculation:
>       *
>       * if (this == o)  return true; // Same reference.
>       * if (!(o instanceof Referrer))  return false;
>       * Object k1 = get();
>       * Object k2 = ((Referrer) o).get();
>       * if ( k1 != null&&  k1.equals(k2)) return true;
>       * return ( k1 == null&&  k2 == null&&  hashCode() == o.hashCode());
>       *
>       * @see Ref
>       * @param o
>       * @return
>       */
>      public boolean equals(Object o);
>
>      /**
>       * Standard hashCode calculation for IDENTITY based references,
> where k
>       * is the referent.
>       *
>       * int hash = 7;
>       * hash = 29 * hash + System.identityHashCode(k);
>       * hash = 29 * hash + k.getClass().hashCode();
>       *
>       * For non IDENTITY references, the hashCode returned is the
> referent's
>       * hashCode, after the reference has been cleared, it reverts to the
>       * IDENTITY based value.  The IDENTITY hashCode should be calculated
>       * at construction time.
>       *
>       * @return
>       */
>      public int hashCode();
> }
>
> Here's an implementation to avoid creating an unnecessary reference:
>
> /*
>   * Licensed to the Apache Software Foundation (ASF) under one
>   * or more contributor license agreements.  See the NOTICE file
>   * distributed with this work for additional information
>   * regarding copyright ownership. The ASF licenses this file
>   * to you under the Apache License, Version 2.0 (the
>   * "License"); you may not use this file except in compliance
>   * with the License. You may obtain a copy of the License at
>   *
>   *      http://www.apache.org/licenses/LICENSE-2.0
>   *
>   * Unless required by applicable law or agreed to in writing, software
>   * distributed under the License is distributed on an "AS IS" BASIS,
>   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
>   * See the License for the specific language governing permissions and
>   * limitations under the License.
>   */
>
> package org.apache.river.impl.util;
>
> /**
>   *
>   * @author peter
>   */
> class TempIdentityReferrer<T>  implements Referrer<T>  {
>
>      private final T t;
>
>      TempIdentityReferrer(T t){
>          if ( t == null ) throw new NullPointerException("Null
> prohibited");
>          this.t = t;
>      }
>
>      @Override
>      public T get() {
>          return t;
>      }
>
>      @Override
>      public void clear() {
>          throw new UnsupportedOperationException("Not supported.");
>      }
>
>      @Override
>      public boolean isEnqueued() {
>          return false;
>      }
>
>      @Override
>      public boolean enqueue() {
>          return false;
>      }
>
>      @Override
>      public boolean equals(Object o) {
>          if (this == o) {
>              return true;
>          } else if (!(o instanceof Referrer)) {
>              return false;
>          }
>          Object t2 = ((Referrer) o).get();
>          return( t == t2 );
>      }
>
>      public int hashCode(){
>          int hash = 7;
>          hash = 29 * hash + System.identityHashCode(t);
>          hash = 29 * hash + t.getClass().hashCode();
>          return hash;
>      }
>
> }
>
>
> This is an implementation for a permanent Reference:
>
> /*
>   * Licensed to the Apache Software Foundation (ASF) under one
>   * or more contributor license agreements.  See the NOTICE file
>   * distributed with this work for additional information
>   * regarding copyright ownership. The ASF licenses this file
>   * to you under the Apache License, Version 2.0 (the
>   * "License"); you may not use this file except in compliance
>   * with the License. You may obtain a copy of the License at
>   *
>   *      http://www.apache.org/licenses/LICENSE-2.0
>   *
>   * Unless required by applicable law or agreed to in writing, software
>   * distributed under the License is distributed on an "AS IS" BASIS,
>   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
>   * See the License for the specific language governing permissions and
>   * limitations under the License.
>   */
>
> package org.apache.river.impl.util;
>
> import java.io.InvalidObjectException;
> import java.io.ObjectInputStream;
> import java.io.Serializable;
> import java.lang.ref.ReferenceQueue;
> import java.lang.ref.SoftReference;
>
> /**
>   * Implementation as per Ref.SOFT_IDENTITY
>   *
>   * @see Ref#SOFT_IDENTITY
>   * @author Peter Firmstone.
>   */
> class SoftIdentityReferenceKey<T>  extends SoftReference<T>  implements
> Referrer<T>, Serializable{
>      private static final long serialVersionUID = 1L;
>      private final int hash;
>
>      SoftIdentityReferenceKey(T k, ReferenceQueue<? super T>  q) {
>          super(k,q);
>          int hash = 7;
>          hash = 29 * hash + System.identityHashCode(k);
>          hash = 29 * hash + k.getClass().hashCode();
>          this.hash = hash;
>      }
>
>      @Override
>      public boolean equals(Object o) {
>          if (this == o) return true;
>          if (!(o instanceof Referrer)) return false;
>          Object k1 = get();
>          Object k2 = ((Referrer) o).get();
>          if ( k1 != null&&  k1 == k2 ) return true;
>          return ( k1 == null&&  k2 == null&&  hashCode() ==
> o.hashCode());
>      }
>
>      @Override
>      public int hashCode() {
>          return hash;
>      }
>
>      @Override
>      public String toString(){
>          Object s = get();
>          if (s != null) return s.toString();
>          return super.toString();
>      }
>
>      private Object writeReplace() {
>          // returns a Builder instead of this class.
>          return ReferenceSerializationFactory.create(get());
>      }
>
>      private void readObject(ObjectInputStream stream)
>              throws InvalidObjectException{
>          throw new InvalidObjectException("Factory required");
>      }
>
> }
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120105/d91b6582/attachment.html>


More information about the Concurrency-interest mailing list