Source Code Cross Referenced for AtomicIntegerFieldUpdater.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 int} fields of designated classes.
044         * This class is designed for use in atomic data structures in which
045         * several fields of the same node are independently subject to atomic
046         * updates.
047         *
048         * <p>Note that the guarantees of the {@code compareAndSet}
049         * method in this class are weaker than in other atomic classes.
050         * Because this class cannot ensure that all uses of the field
051         * are appropriate for purposes of atomic access, it can
052         * guarantee atomicity only with respect to other invocations of
053         * {@code compareAndSet} and {@code set} on the same updater.
054         *
055         * @since 1.5
056         * @author Doug Lea
057         * @param <T> The type of the object holding the updatable field
058         */
059        public abstract class AtomicIntegerFieldUpdater<T> {
060            /**
061             * Creates and returns an updater for objects with the given field.
062             * The Class argument is needed to check that reflective types and
063             * generic types match.
064             *
065             * @param tclass the class of the objects holding the field
066             * @param fieldName the name of the field to be updated
067             * @return the updater
068             * @throws IllegalArgumentException if the field is not a
069             * volatile integer type
070             * @throws RuntimeException with a nested reflection-based
071             * exception if the class does not hold field or is the wrong type
072             */
073            public static <U> AtomicIntegerFieldUpdater<U> newUpdater(
074                    Class<U> tclass, String fieldName) {
075                return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName);
076            }
077
078            /**
079             * Protected do-nothing constructor for use by subclasses.
080             */
081            protected AtomicIntegerFieldUpdater() {
082            }
083
084            /**
085             * Atomically sets the field of the given object managed by this updater
086             * to the given updated value if the current value {@code ==} the
087             * expected value. This method is guaranteed to be atomic with respect to
088             * other calls to {@code compareAndSet} and {@code set}, but not
089             * necessarily with respect to other changes in the field.
090             *
091             * @param obj An object whose field to conditionally set
092             * @param expect the expected value
093             * @param update the new value
094             * @return true if successful
095             * @throws ClassCastException if {@code obj} is not an instance
096             * of the class possessing the field established in the constructor
097             */
098            public abstract boolean compareAndSet(T obj, int expect, int update);
099
100            /**
101             * Atomically sets the field of the given object managed by this updater
102             * to the given updated value if the current value {@code ==} the
103             * expected value. This method is guaranteed to be atomic with respect to
104             * other calls to {@code compareAndSet} and {@code set}, but not
105             * necessarily with respect to other changes in the field.
106             *
107             * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
108             * and does not provide ordering guarantees, so is only rarely an
109             * appropriate alternative to {@code compareAndSet}.
110             *
111             * @param obj An object whose field to conditionally set
112             * @param expect the expected value
113             * @param update the new value
114             * @return true if successful
115             * @throws ClassCastException if {@code obj} is not an instance
116             * of the class possessing the field established in the constructor
117             */
118            public abstract boolean weakCompareAndSet(T obj, int expect,
119                    int update);
120
121            /**
122             * Sets the field of the given object managed by this updater to the
123             * given updated value. This operation is guaranteed to act as a volatile
124             * store with respect to subsequent invocations of {@code compareAndSet}.
125             *
126             * @param obj An object whose field to set
127             * @param newValue the new value
128             */
129            public abstract void set(T obj, int newValue);
130
131            /**
132             * Eventually sets the field of the given object managed by this
133             * updater to the given updated value.
134             *
135             * @param obj An object whose field to set
136             * @param newValue the new value
137             * @since 1.6
138             */
139            public abstract void lazySet(T obj, int newValue);
140
141            /**
142             * Gets the current value held in the field of the given object managed
143             * by this updater.
144             *
145             * @param obj An object whose field to get
146             * @return the current value
147             */
148            public abstract int get(T obj);
149
150            /**
151             * Atomically sets the field of the given object managed by this updater
152             * to the given value and returns the old value.
153             *
154             * @param obj An object whose field to get and set
155             * @param newValue the new value
156             * @return the previous value
157             */
158            public int getAndSet(T obj, int newValue) {
159                for (;;) {
160                    int current = get(obj);
161                    if (compareAndSet(obj, current, newValue))
162                        return current;
163                }
164            }
165
166            /**
167             * Atomically increments by one the current value of the field of the
168             * given object managed by this updater.
169             *
170             * @param obj An object whose field to get and set
171             * @return the previous value
172             */
173            public int getAndIncrement(T obj) {
174                for (;;) {
175                    int current = get(obj);
176                    int next = current + 1;
177                    if (compareAndSet(obj, current, next))
178                        return current;
179                }
180            }
181
182            /**
183             * Atomically decrements by one the current value of the field of the
184             * given object managed by this updater.
185             *
186             * @param obj An object whose field to get and set
187             * @return the previous value
188             */
189            public int getAndDecrement(T obj) {
190                for (;;) {
191                    int current = get(obj);
192                    int next = current - 1;
193                    if (compareAndSet(obj, current, next))
194                        return current;
195                }
196            }
197
198            /**
199             * Atomically adds the given value to the current value of the field of
200             * the given object managed by this updater.
201             *
202             * @param obj An object whose field to get and set
203             * @param delta the value to add
204             * @return the previous value
205             */
206            public int getAndAdd(T obj, int delta) {
207                for (;;) {
208                    int current = get(obj);
209                    int next = current + delta;
210                    if (compareAndSet(obj, current, next))
211                        return current;
212                }
213            }
214
215            /**
216             * Atomically increments by one the current value of the field of the
217             * given object managed by this updater.
218             *
219             * @param obj An object whose field to get and set
220             * @return the updated value
221             */
222            public int incrementAndGet(T obj) {
223                for (;;) {
224                    int current = get(obj);
225                    int next = current + 1;
226                    if (compareAndSet(obj, current, next))
227                        return next;
228                }
229            }
230
231            /**
232             * Atomically decrements by one the current value of the field of the
233             * given object managed by this updater.
234             *
235             * @param obj An object whose field to get and set
236             * @return the updated value
237             */
238            public int decrementAndGet(T obj) {
239                for (;;) {
240                    int current = get(obj);
241                    int next = current - 1;
242                    if (compareAndSet(obj, current, next))
243                        return next;
244                }
245            }
246
247            /**
248             * Atomically adds the given value to the current value of the field of
249             * the given object managed by this updater.
250             *
251             * @param obj An object whose field to get and set
252             * @param delta the value to add
253             * @return the updated value
254             */
255            public int addAndGet(T obj, int delta) {
256                for (;;) {
257                    int current = get(obj);
258                    int next = current + delta;
259                    if (compareAndSet(obj, current, next))
260                        return next;
261                }
262            }
263
264            /**
265             * Standard hotspot implementation using intrinsics
266             */
267            private static class AtomicIntegerFieldUpdaterImpl<T> extends
268                    AtomicIntegerFieldUpdater<T> {
269                private static final Unsafe unsafe = Unsafe.getUnsafe();
270                private final long offset;
271                private final Class<T> tclass;
272                private final Class cclass;
273
274                AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName) {
275                    Field field = null;
276                    Class caller = null;
277                    int modifiers = 0;
278                    try {
279                        field = tclass.getDeclaredField(fieldName);
280                        caller = sun.reflect.Reflection.getCallerClass(3);
281                        modifiers = field.getModifiers();
282                        sun.reflect.misc.ReflectUtil.ensureMemberAccess(caller,
283                                tclass, null, modifiers);
284                        sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
285                    } catch (Exception ex) {
286                        throw new RuntimeException(ex);
287                    }
288
289                    Class fieldt = field.getType();
290                    if (fieldt != int.class)
291                        throw new IllegalArgumentException(
292                                "Must be integer type");
293
294                    if (!Modifier.isVolatile(modifiers))
295                        throw new IllegalArgumentException(
296                                "Must be volatile type");
297
298                    this .cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller
299                            : null;
300                    this .tclass = tclass;
301                    offset = unsafe.objectFieldOffset(field);
302                }
303
304                private void fullCheck(T obj) {
305                    if (!tclass.isInstance(obj))
306                        throw new ClassCastException();
307                    if (cclass != null)
308                        ensureProtectedAccess(obj);
309                }
310
311                public boolean compareAndSet(T obj, int expect, int update) {
312                    if (obj == null || obj.getClass() != tclass
313                            || cclass != null)
314                        fullCheck(obj);
315                    return unsafe
316                            .compareAndSwapInt(obj, offset, expect, update);
317                }
318
319                public boolean weakCompareAndSet(T obj, int expect, int update) {
320                    if (obj == null || obj.getClass() != tclass
321                            || cclass != null)
322                        fullCheck(obj);
323                    return unsafe
324                            .compareAndSwapInt(obj, offset, expect, update);
325                }
326
327                public void set(T obj, int newValue) {
328                    if (obj == null || obj.getClass() != tclass
329                            || cclass != null)
330                        fullCheck(obj);
331                    unsafe.putIntVolatile(obj, offset, newValue);
332                }
333
334                public void lazySet(T obj, int newValue) {
335                    if (obj == null || obj.getClass() != tclass
336                            || cclass != null)
337                        fullCheck(obj);
338                    unsafe.putOrderedInt(obj, offset, newValue);
339                }
340
341                public final int get(T obj) {
342                    if (obj == null || obj.getClass() != tclass
343                            || cclass != null)
344                        fullCheck(obj);
345                    return unsafe.getIntVolatile(obj, offset);
346                }
347
348                private void ensureProtectedAccess(T obj) {
349                    if (cclass.isInstance(obj)) {
350                        return;
351                    }
352                    throw new RuntimeException(
353                            new IllegalAccessException(
354                                    "Class "
355                                            + cclass.getName()
356                                            + " can not access a protected member of class "
357                                            + tclass.getName()
358                                            + " using an instance of "
359                                            + obj.getClass().getName()));
360                }
361            }
362        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.