Source Code Cross Referenced for AtomicReferenceFieldUpdater.java in  » 6.0-JDK-Core » Collections-Jar-Zip-Logging-regex » java » util » concurrent » atomic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » Collections Jar Zip Logging regex » java.util.concurrent.atomic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
003         *
004         * This code is free software; you can redistribute it and/or modify it
005         * under the terms of the GNU General Public License version 2 only, as
006         * published by the Free Software Foundation.  Sun designates this
007         * particular file as subject to the "Classpath" exception as provided
008         * by Sun in the LICENSE file that accompanied this code.
009         *
010         * This code is distributed in the hope that it will be useful, but WITHOUT
011         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
013         * version 2 for more details (a copy is included in the LICENSE file that
014         * accompanied this code).
015         *
016         * You should have received a copy of the GNU General Public License version
017         * 2 along with this work; if not, write to the Free Software Foundation,
018         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
019         *
020         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
021         * CA 95054 USA or visit www.sun.com if you need additional information or
022         * have any questions.
023         */
024
025        /*
026         * This file is available under and governed by the GNU General Public
027         * License version 2 only, as published by the Free Software Foundation.
028         * However, the following notice accompanied the original version of this
029         * file:
030         *
031         * Written by Doug Lea with assistance from members of JCP JSR-166
032         * Expert Group and released to the public domain, as explained at
033         * http://creativecommons.org/licenses/publicdomain
034         */
035
036        package java.util.concurrent.atomic;
037
038        import sun.misc.Unsafe;
039        import java.lang.reflect.*;
040
041        /**
042         * A reflection-based utility that enables atomic updates to
043         * designated {@code volatile} reference fields of designated
044         * classes.  This class is designed for use in atomic data structures
045         * in which several reference fields of the same node are
046         * independently subject to atomic updates. For example, a tree node
047         * might be declared as
048         *
049         * <pre>
050         * class Node {
051         *   private volatile Node left, right;
052         *
053         *   private static final AtomicReferenceFieldUpdater&lt;Node, Node&gt; leftUpdater =
054         *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
055         *   private static AtomicReferenceFieldUpdater&lt;Node, Node&gt; rightUpdater =
056         *     AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
057         *
058         *   Node getLeft() { return left;  }
059         *   boolean compareAndSetLeft(Node expect, Node update) {
060         *     return leftUpdater.compareAndSet(this, expect, update);
061         *   }
062         *   // ... and so on
063         * }
064         * </pre>
065         *
066         * <p>Note that the guarantees of the {@code compareAndSet}
067         * method in this class are weaker than in other atomic classes.
068         * Because this class cannot ensure that all uses of the field
069         * are appropriate for purposes of atomic access, it can
070         * guarantee atomicity only with respect to other invocations of
071         * {@code compareAndSet} and {@code set} on the same updater.
072         *
073         * @since 1.5
074         * @author Doug Lea
075         * @param <T> The type of the object holding the updatable field
076         * @param <V> The type of the field
077         */
078        public abstract class AtomicReferenceFieldUpdater<T, V> {
079
080            /**
081             * Creates and returns an updater for objects with the given field.
082             * The Class arguments are needed to check that reflective types and
083             * generic types match.
084             *
085             * @param tclass the class of the objects holding the field.
086             * @param vclass the class of the field
087             * @param fieldName the name of the field to be updated.
088             * @return the updater
089             * @throws IllegalArgumentException if the field is not a volatile reference type.
090             * @throws RuntimeException with a nested reflection-based
091             * exception if the class does not hold field or is the wrong type.
092             */
093            public static <U, W> AtomicReferenceFieldUpdater<U, W> newUpdater(
094                    Class<U> tclass, Class<W> vclass, String fieldName) {
095                return new AtomicReferenceFieldUpdaterImpl<U, W>(tclass,
096                        vclass, fieldName);
097            }
098
099            /**
100             * Protected do-nothing constructor for use by subclasses.
101             */
102            protected AtomicReferenceFieldUpdater() {
103            }
104
105            /**
106             * Atomically sets the field of the given object managed by this updater
107             * to the given updated value if the current value {@code ==} the
108             * expected value. This method is guaranteed to be atomic with respect to
109             * other calls to {@code compareAndSet} and {@code set}, but not
110             * necessarily with respect to other changes in the field.
111             *
112             * @param obj An object whose field to conditionally set
113             * @param expect the expected value
114             * @param update the new value
115             * @return true if successful.
116             */
117            public abstract boolean compareAndSet(T obj, V expect, V update);
118
119            /**
120             * Atomically sets the field of the given object managed by this updater
121             * to the given updated value if the current value {@code ==} the
122             * expected value. This method is guaranteed to be atomic with respect to
123             * other calls to {@code compareAndSet} and {@code set}, but not
124             * necessarily with respect to other changes in the field.
125             *
126             * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
127             * and does not provide ordering guarantees, so is only rarely an
128             * appropriate alternative to {@code compareAndSet}.
129             *
130             * @param obj An object whose field to conditionally set
131             * @param expect the expected value
132             * @param update the new value
133             * @return true if successful.
134             */
135            public abstract boolean weakCompareAndSet(T obj, V expect, V update);
136
137            /**
138             * Sets the field of the given object managed by this updater to the
139             * given updated value. This operation is guaranteed to act as a volatile
140             * store with respect to subsequent invocations of {@code compareAndSet}.
141             *
142             * @param obj An object whose field to set
143             * @param newValue the new value
144             */
145            public abstract void set(T obj, V newValue);
146
147            /**
148             * Eventually sets the field of the given object managed by this
149             * updater to the given updated value.
150             *
151             * @param obj An object whose field to set
152             * @param newValue the new value
153             * @since 1.6
154             */
155            public abstract void lazySet(T obj, V newValue);
156
157            /**
158             * Gets the current value held in the field of the given object managed
159             * by this updater.
160             *
161             * @param obj An object whose field to get
162             * @return the current value
163             */
164            public abstract V get(T obj);
165
166            /**
167             * Atomically sets the field of the given object managed by this updater
168             * to the given value and returns the old value.
169             *
170             * @param obj An object whose field to get and set
171             * @param newValue the new value
172             * @return the previous value
173             */
174            public V getAndSet(T obj, V newValue) {
175                for (;;) {
176                    V current = get(obj);
177                    if (compareAndSet(obj, current, newValue))
178                        return current;
179                }
180            }
181
182            private static final class AtomicReferenceFieldUpdaterImpl<T, V>
183                    extends AtomicReferenceFieldUpdater<T, V> {
184                private static final Unsafe unsafe = Unsafe.getUnsafe();
185                private final long offset;
186                private final Class<T> tclass;
187                private final Class<V> vclass;
188                private final Class cclass;
189
190                /*
191                 * Internal type checks within all update methods contain
192                 * internal inlined optimizations checking for the common
193                 * cases where the class is final (in which case a simple
194                 * getClass comparison suffices) or is of type Object (in
195                 * which case no check is needed because all objects are
196                 * instances of Object). The Object case is handled simply by
197                 * setting vclass to null in constructor.  The targetCheck and
198                 * updateCheck methods are invoked when these faster
199                 * screenings fail.
200                 */
201
202                AtomicReferenceFieldUpdaterImpl(Class<T> tclass,
203                        Class<V> vclass, String fieldName) {
204                    Field field = null;
205                    Class fieldClass = null;
206                    Class caller = null;
207                    int modifiers = 0;
208                    try {
209                        field = tclass.getDeclaredField(fieldName);
210                        caller = sun.reflect.Reflection.getCallerClass(3);
211                        modifiers = field.getModifiers();
212                        sun.reflect.misc.ReflectUtil.ensureMemberAccess(caller,
213                                tclass, null, modifiers);
214                        sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
215                        fieldClass = field.getType();
216                    } catch (Exception ex) {
217                        throw new RuntimeException(ex);
218                    }
219
220                    if (vclass != fieldClass)
221                        throw new ClassCastException();
222
223                    if (!Modifier.isVolatile(modifiers))
224                        throw new IllegalArgumentException(
225                                "Must be volatile type");
226
227                    this .cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller
228                            : null;
229                    this .tclass = tclass;
230                    if (vclass == Object.class)
231                        this .vclass = null;
232                    else
233                        this .vclass = vclass;
234                    offset = unsafe.objectFieldOffset(field);
235                }
236
237                void targetCheck(T obj) {
238                    if (!tclass.isInstance(obj))
239                        throw new ClassCastException();
240                    if (cclass != null)
241                        ensureProtectedAccess(obj);
242                }
243
244                void updateCheck(T obj, V update) {
245                    if (!tclass.isInstance(obj)
246                            || (update != null && vclass != null && !vclass
247                                    .isInstance(update)))
248                        throw new ClassCastException();
249                    if (cclass != null)
250                        ensureProtectedAccess(obj);
251                }
252
253                public boolean compareAndSet(T obj, V expect, V update) {
254                    if (obj == null
255                            || obj.getClass() != tclass
256                            || cclass != null
257                            || (update != null && vclass != null && vclass != update
258                                    .getClass()))
259                        updateCheck(obj, update);
260                    return unsafe.compareAndSwapObject(obj, offset, expect,
261                            update);
262                }
263
264                public boolean weakCompareAndSet(T obj, V expect, V update) {
265                    // same implementation as strong form for now
266                    if (obj == null
267                            || obj.getClass() != tclass
268                            || cclass != null
269                            || (update != null && vclass != null && vclass != update
270                                    .getClass()))
271                        updateCheck(obj, update);
272                    return unsafe.compareAndSwapObject(obj, offset, expect,
273                            update);
274                }
275
276                public void set(T obj, V newValue) {
277                    if (obj == null
278                            || obj.getClass() != tclass
279                            || cclass != null
280                            || (newValue != null && vclass != null && vclass != newValue
281                                    .getClass()))
282                        updateCheck(obj, newValue);
283                    unsafe.putObjectVolatile(obj, offset, newValue);
284                }
285
286                public void lazySet(T obj, V newValue) {
287                    if (obj == null
288                            || obj.getClass() != tclass
289                            || cclass != null
290                            || (newValue != null && vclass != null && vclass != newValue
291                                    .getClass()))
292                        updateCheck(obj, newValue);
293                    unsafe.putOrderedObject(obj, offset, newValue);
294                }
295
296                public V get(T obj) {
297                    if (obj == null || obj.getClass() != tclass
298                            || cclass != null)
299                        targetCheck(obj);
300                    return (V) unsafe.getObjectVolatile(obj, offset);
301                }
302
303                private void ensureProtectedAccess(T obj) {
304                    if (cclass.isInstance(obj)) {
305                        return;
306                    }
307                    throw new RuntimeException(
308                            new IllegalAccessException(
309                                    "Class "
310                                            + cclass.getName()
311                                            + " can not access a protected member of class "
312                                            + tclass.getName()
313                                            + " using an instance of "
314                                            + obj.getClass().getName()));
315                }
316            }
317        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.