src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/WeakObjectPool.java
changeset 50614 3810c9a2efa1
child 59240 b3116877866f
equal deleted inserted replaced
50613:0f93a75b9213 50614:3810c9a2efa1
       
     1 /*
       
     2  * reserved comment block
       
     3  * DO NOT REMOVE OR ALTER!
       
     4  */
       
     5 /**
       
     6  * Licensed to the Apache Software Foundation (ASF) under one
       
     7  * or more contributor license agreements. See the NOTICE file
       
     8  * distributed with this work for additional information
       
     9  * regarding copyright ownership. The ASF licenses this file
       
    10  * to you under the Apache License, Version 2.0 (the
       
    11  * "License"); you may not use this file except in compliance
       
    12  * with the License. You may obtain a copy of the License at
       
    13  *
       
    14  * http://www.apache.org/licenses/LICENSE-2.0
       
    15  *
       
    16  * Unless required by applicable law or agreed to in writing,
       
    17  * software distributed under the License is distributed on an
       
    18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       
    19  * KIND, either express or implied. See the License for the
       
    20  * specific language governing permissions and limitations
       
    21  * under the License.
       
    22  */
       
    23 package com.sun.org.apache.xml.internal.security.utils;
       
    24 
       
    25 import java.lang.ref.WeakReference;
       
    26 import java.util.Collections;
       
    27 import java.util.Map;
       
    28 import java.util.WeakHashMap;
       
    29 import java.util.concurrent.BlockingQueue;
       
    30 import java.util.concurrent.LinkedBlockingDeque;
       
    31 
       
    32 /**
       
    33  * Abstract base class for pooling objects.  The two public methods are
       
    34  * {@link #getObject()} and ({@link #repool(Object)}.  Objects are held through
       
    35  * weak references so even objects that are not repooled are subject to garbage collection.
       
    36  *
       
    37  * Subclasses must implement the abstract {@link #createObject()}.
       
    38  * <p>
       
    39  *
       
    40  * Internally, the pool is stored in a java.util.concurrent.LinkedBlockingDeque
       
    41  * instance.
       
    42  */
       
    43 public abstract class WeakObjectPool<T, E extends Throwable> {
       
    44 
       
    45     private static final Integer MARKER_VALUE = Integer.MAX_VALUE;//once here rather than auto-box it?
       
    46 
       
    47     /** created, available objects to be checked out to clients */
       
    48     private final BlockingQueue<WeakReference<T>> available;
       
    49 
       
    50     /**
       
    51      * Synchronized, identity map of loaned out objects (WeakHashMap);
       
    52      * use to ensure we repool only object originating from here
       
    53      * and do it once.
       
    54      */
       
    55     private final Map<T, Integer> onLoan;
       
    56 
       
    57     /**
       
    58      * The lone constructor.
       
    59      */
       
    60     protected WeakObjectPool() {
       
    61         //alternative implementations: ArrayBlockingQueue has a fixed size
       
    62         //  PriorityBlockingQueue: requires a dummy comparator; less memory but more overhead
       
    63         available = new LinkedBlockingDeque<WeakReference<T>>();
       
    64         this.onLoan = Collections.synchronizedMap(new WeakHashMap<T, Integer>());
       
    65     }
       
    66 
       
    67     /**
       
    68      * Called whenever a new pool object is desired; subclasses must implement.
       
    69      *
       
    70      * @return object of the type desired by the subclass
       
    71      * @throws E Throwable's subclass
       
    72      */
       
    73     protected abstract T createObject() throws E;
       
    74 
       
    75 
       
    76     /**
       
    77      * Subclasses can subclass to return a more specific type.
       
    78      *
       
    79      * @return an object from the pool; will block until an object is available
       
    80      * @throws E
       
    81      */
       
    82     public T getObject() throws E {
       
    83         WeakReference<T> ref;
       
    84         T retValue = null;
       
    85         do {
       
    86             //remove any stale entries as well
       
    87             ref = available.poll();
       
    88         } while (ref != null && (retValue = ref.get()) == null);
       
    89 
       
    90         if (retValue == null) {
       
    91             //empty pool; create & add new one
       
    92             retValue = createObject();
       
    93         }
       
    94         onLoan.put(retValue, MARKER_VALUE);
       
    95         return retValue;
       
    96     }
       
    97 
       
    98 
       
    99     /**
       
   100      * Adds the given object to the pool, provided that the object
       
   101      * was created by this pool.
       
   102      *
       
   103      * @param obj the object to return to the pool
       
   104      * @return whether the object was successfully added as available
       
   105      */
       
   106     public boolean repool(T obj) {
       
   107         if (obj != null && onLoan.containsKey(obj)) {
       
   108             //synchronize to protect against a caller returning the same object again...
       
   109             synchronized (obj) {
       
   110                 //...and check to see that it was removed
       
   111                 if (onLoan.remove(obj) != null) {
       
   112                     return available.offer(new WeakReference<T>(obj));
       
   113                 }
       
   114             }
       
   115         }
       
   116         return false;
       
   117     }
       
   118 }