Thu, 31 Aug 2017 15:18:52 +0800
merge
1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.ws.util;
28 import com.sun.xml.internal.ws.api.pipe.Tube;
29 import com.sun.xml.internal.ws.api.pipe.TubeCloner;
31 import javax.xml.bind.JAXBContext;
32 import javax.xml.bind.JAXBException;
33 import java.util.concurrent.ConcurrentLinkedQueue;
34 import java.lang.ref.WeakReference;
36 /**
37 * General-purpose object pool.
38 *
39 * <p>
40 * In many parts of the runtime, we need to pool instances of objects that
41 * are expensive to create (such as JAXB objects, StAX parsers, {@link Tube} instances.)
42 *
43 * <p>
44 * This class provides a default implementation of such a pool.
45 *
46 * TODO: improve the implementation
47 *
48 * @author Kohsuke Kawaguchi
49 */
50 public abstract class Pool<T> {
52 // volatile since multiple threads may access queue reference
53 private volatile WeakReference<ConcurrentLinkedQueue<T>> queue;
55 /**
56 * Gets a new object from the pool.
57 *
58 * <p>
59 * If no object is available in the pool, this method creates a new one.
60 *
61 * @return
62 * always non-null.
63 */
64 public final T take() {
65 T t = getQueue().poll();
66 if(t==null)
67 return create();
68 return t;
69 }
71 private ConcurrentLinkedQueue<T> getQueue() {
72 WeakReference<ConcurrentLinkedQueue<T>> q = queue;
73 if (q != null) {
74 ConcurrentLinkedQueue<T> d = q.get();
75 if (d != null)
76 return d;
77 }
79 // overwrite the queue
80 ConcurrentLinkedQueue<T> d = new ConcurrentLinkedQueue<T>();
81 queue = new WeakReference<ConcurrentLinkedQueue<T>>(d);
83 return d;
84 }
86 /**
87 * Returns an object back to the pool.
88 */
89 public final void recycle(T t) {
90 getQueue().offer(t);
91 }
93 /**
94 * Creates a new instance of object.
95 *
96 * <p>
97 * This method is used when someone wants to
98 * {@link #take() take} an object from an empty pool.
99 *
100 * <p>
101 * Also note that multiple threads may call this method
102 * concurrently.
103 */
104 protected abstract T create();
107 /**
108 * JAXB {@link javax.xml.bind.Marshaller} pool.
109 */
110 public static final class Marshaller extends Pool<javax.xml.bind.Marshaller> {
111 private final JAXBContext context;
113 public Marshaller(JAXBContext context) {
114 this.context = context;
115 }
117 @Override
118 protected javax.xml.bind.Marshaller create() {
119 try {
120 return context.createMarshaller();
121 } catch (JAXBException e) {
122 // impossible
123 throw new AssertionError(e);
124 }
125 }
126 }
128 /**
129 * JAXB {@link javax.xml.bind.Marshaller} pool.
130 */
131 public static final class Unmarshaller extends Pool<javax.xml.bind.Unmarshaller> {
132 private final JAXBContext context;
134 public Unmarshaller(JAXBContext context) {
135 this.context = context;
136 }
138 @Override
139 protected javax.xml.bind.Unmarshaller create() {
140 try {
141 return context.createUnmarshaller();
142 } catch (JAXBException e) {
143 // impossible
144 throw new AssertionError(e);
145 }
146 }
147 }
149 /**
150 * {@link Tube} pool.
151 */
152 public static final class TubePool extends Pool<Tube> {
153 private final Tube master;
155 public TubePool(Tube master) {
156 this.master = master;
157 recycle(master); // we'll use master as a part of the pool, too.
158 }
160 @Override
161 protected Tube create() {
162 return TubeCloner.clone(master);
163 }
165 /**
166 *
167 * @return master tubeline from pool
168 * @deprecated Expected to be used in rare cases where access to master
169 * tubeline is required and safe, such as Stub.close()."
170 */
171 @Deprecated()
172 public final Tube takeMaster() {
173 return master;
174 }
176 }
177 }