Source Code Cross Referenced for AtomicLongFieldUpdater.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 long} 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 AtomicLongFieldUpdater<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 long 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> AtomicLongFieldUpdater<U> newUpdater(
074                    Class<U> tclass, String fieldName) {
075                if (AtomicLong.VM_SUPPORTS_LONG_CAS)
076                    return new CASUpdater<U>(tclass, fieldName);
077                else
078                    return new LockedUpdater<U>(tclass, fieldName);
079            }
080
081            /**
082             * Protected do-nothing constructor for use by subclasses.
083             */
084            protected AtomicLongFieldUpdater() {
085            }
086
087            /**
088             * Atomically sets the field of the given object managed by this updater
089             * to the given updated value if the current value {@code ==} the
090             * expected value. This method is guaranteed to be atomic with respect to
091             * other calls to {@code compareAndSet} and {@code set}, but not
092             * necessarily with respect to other changes in the field.
093             *
094             * @param obj An object whose field to conditionally set
095             * @param expect the expected value
096             * @param update the new value
097             * @return true if successful.
098             * @throws ClassCastException if {@code obj} is not an instance
099             * of the class possessing the field established in the constructor.
100             */
101            public abstract boolean compareAndSet(T obj, long expect,
102                    long update);
103
104            /**
105             * Atomically sets the field of the given object managed by this updater
106             * to the given updated value if the current value {@code ==} the
107             * expected value. This method is guaranteed to be atomic with respect to
108             * other calls to {@code compareAndSet} and {@code set}, but not
109             * necessarily with respect to other changes in the field.
110             *
111             * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
112             * and does not provide ordering guarantees, so is only rarely an
113             * appropriate alternative to {@code compareAndSet}.
114             *
115             * @param obj An object whose field to conditionally set
116             * @param expect the expected value
117             * @param update the new value
118             * @return true if successful.
119             * @throws ClassCastException if {@code obj} is not an instance
120             * of the class possessing the field established in the constructor.
121             */
122            public abstract boolean weakCompareAndSet(T obj, long expect,
123                    long update);
124
125            /**
126             * Sets the field of the given object managed by this updater to the
127             * given updated value. This operation is guaranteed to act as a volatile
128             * store with respect to subsequent invocations of {@code compareAndSet}.
129             *
130             * @param obj An object whose field to set
131             * @param newValue the new value
132             */
133            public abstract void set(T obj, long newValue);
134
135            /**
136             * Eventually sets the field of the given object managed by this
137             * updater to the given updated value.
138             *
139             * @param obj An object whose field to set
140             * @param newValue the new value
141             * @since 1.6
142             */
143            public abstract void lazySet(T obj, long newValue);
144
145            /**
146             * Gets the current value held in the field of the given object managed
147             * by this updater.
148             *
149             * @param obj An object whose field to get
150             * @return the current value
151             */
152            public abstract long get(T obj);
153
154            /**
155             * Atomically sets the field of the given object managed by this updater
156             * to the given value and returns the old value.
157             *
158             * @param obj An object whose field to get and set
159             * @param newValue the new value
160             * @return the previous value
161             */
162            public long getAndSet(T obj, long newValue) {
163                for (;;) {
164                    long current = get(obj);
165                    if (compareAndSet(obj, current, newValue))
166                        return current;
167                }
168            }
169
170            /**
171             * Atomically increments by one the current value of the field of the
172             * given object managed by this updater.
173             *
174             * @param obj An object whose field to get and set
175             * @return the previous value
176             */
177            public long getAndIncrement(T obj) {
178                for (;;) {
179                    long current = get(obj);
180                    long next = current + 1;
181                    if (compareAndSet(obj, current, next))
182                        return current;
183                }
184            }
185
186            /**
187             * Atomically decrements by one the current value of the field of the
188             * given object managed by this updater.
189             *
190             * @param obj An object whose field to get and set
191             * @return the previous value
192             */
193            public long getAndDecrement(T obj) {
194                for (;;) {
195                    long current = get(obj);
196                    long next = current - 1;
197                    if (compareAndSet(obj, current, next))
198                        return current;
199                }
200            }
201
202            /**
203             * Atomically adds the given value to the current value of the field of
204             * the given object managed by this updater.
205             *
206             * @param obj An object whose field to get and set
207             * @param delta the value to add
208             * @return the previous value
209             */
210            public long getAndAdd(T obj, long delta) {
211                for (;;) {
212                    long current = get(obj);
213                    long next = current + delta;
214                    if (compareAndSet(obj, current, next))
215                        return current;
216                }
217            }
218
219            /**
220             * Atomically increments by one the current value of the field of the
221             * given object managed by this updater.
222             *
223             * @param obj An object whose field to get and set
224             * @return the updated value
225             */
226            public long incrementAndGet(T obj) {
227                for (;;) {
228                    long current = get(obj);
229                    long next = current + 1;
230                    if (compareAndSet(obj, current, next))
231                        return next;
232                }
233            }
234
235            /**
236             * Atomically decrements by one the current value of the field of the
237             * given object managed by this updater.
238             *
239             * @param obj An object whose field to get and set
240             * @return the updated value
241             */
242            public long decrementAndGet(T obj) {
243                for (;;) {
244                    long current = get(obj);
245                    long next = current - 1;
246                    if (compareAndSet(obj, current, next))
247                        return next;
248                }
249            }
250
251            /**
252             * Atomically adds the given value to the current value of the field of
253             * the given object managed by this updater.
254             *
255             * @param obj An object whose field to get and set
256             * @param delta the value to add
257             * @return the updated value
258             */
259            public long addAndGet(T obj, long delta) {
260                for (;;) {
261                    long current = get(obj);
262                    long next = current + delta;
263                    if (compareAndSet(obj, current, next))
264                        return next;
265                }
266            }
267
268            private static class CASUpdater<T> extends
269                    AtomicLongFieldUpdater<T> {
270                private static final Unsafe unsafe = Unsafe.getUnsafe();
271                private final long offset;
272                private final Class<T> tclass;
273                private final Class cclass;
274
275                CASUpdater(Class<T> tclass, String fieldName) {
276                    Field field = null;
277                    Class caller = null;
278                    int modifiers = 0;
279                    try {
280                        field = tclass.getDeclaredField(fieldName);
281                        caller = sun.reflect.Reflection.getCallerClass(3);
282                        modifiers = field.getModifiers();
283                        sun.reflect.misc.ReflectUtil.ensureMemberAccess(caller,
284                                tclass, null, modifiers);
285                        sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
286                    } catch (Exception ex) {
287                        throw new RuntimeException(ex);
288                    }
289
290                    Class fieldt = field.getType();
291                    if (fieldt != long.class)
292                        throw new IllegalArgumentException("Must be long 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, long expect, long update) {
312                    if (obj == null || obj.getClass() != tclass
313                            || cclass != null)
314                        fullCheck(obj);
315                    return unsafe.compareAndSwapLong(obj, offset, expect,
316                            update);
317                }
318
319                public boolean weakCompareAndSet(T obj, long expect, long update) {
320                    if (obj == null || obj.getClass() != tclass
321                            || cclass != null)
322                        fullCheck(obj);
323                    return unsafe.compareAndSwapLong(obj, offset, expect,
324                            update);
325                }
326
327                public void set(T obj, long newValue) {
328                    if (obj == null || obj.getClass() != tclass
329                            || cclass != null)
330                        fullCheck(obj);
331                    unsafe.putLongVolatile(obj, offset, newValue);
332                }
333
334                public void lazySet(T obj, long newValue) {
335                    if (obj == null || obj.getClass() != tclass
336                            || cclass != null)
337                        fullCheck(obj);
338                    unsafe.putOrderedLong(obj, offset, newValue);
339                }
340
341                public long get(T obj) {
342                    if (obj == null || obj.getClass() != tclass
343                            || cclass != null)
344                        fullCheck(obj);
345                    return unsafe.getLongVolatile(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
363            private static class LockedUpdater<T> extends
364                    AtomicLongFieldUpdater<T> {
365                private static final Unsafe unsafe = Unsafe.getUnsafe();
366                private final long offset;
367                private final Class<T> tclass;
368                private final Class cclass;
369
370                LockedUpdater(Class<T> tclass, String fieldName) {
371                    Field field = null;
372                    Class caller = null;
373                    int modifiers = 0;
374                    try {
375                        field = tclass.getDeclaredField(fieldName);
376                        caller = sun.reflect.Reflection.getCallerClass(3);
377                        modifiers = field.getModifiers();
378                        sun.reflect.misc.ReflectUtil.ensureMemberAccess(caller,
379                                tclass, null, modifiers);
380                        sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
381                    } catch (Exception ex) {
382                        throw new RuntimeException(ex);
383                    }
384
385                    Class fieldt = field.getType();
386                    if (fieldt != long.class)
387                        throw new IllegalArgumentException("Must be long type");
388
389                    if (!Modifier.isVolatile(modifiers))
390                        throw new IllegalArgumentException(
391                                "Must be volatile type");
392
393                    this .cclass = (Modifier.isProtected(modifiers) && caller != tclass) ? caller
394                            : null;
395                    this .tclass = tclass;
396                    offset = unsafe.objectFieldOffset(field);
397                }
398
399                private void fullCheck(T obj) {
400                    if (!tclass.isInstance(obj))
401                        throw new ClassCastException();
402                    if (cclass != null)
403                        ensureProtectedAccess(obj);
404                }
405
406                public boolean compareAndSet(T obj, long expect, long update) {
407                    if (obj == null || obj.getClass() != tclass
408                            || cclass != null)
409                        fullCheck(obj);
410                    synchronized (this ) {
411                        long v = unsafe.getLong(obj, offset);
412                        if (v != expect)
413                            return false;
414                        unsafe.putLong(obj, offset, update);
415                        return true;
416                    }
417                }
418
419                public boolean weakCompareAndSet(T obj, long expect, long update) {
420                    return compareAndSet(obj, expect, update);
421                }
422
423                public void set(T obj, long newValue) {
424                    if (obj == null || obj.getClass() != tclass
425                            || cclass != null)
426                        fullCheck(obj);
427                    synchronized (this ) {
428                        unsafe.putLong(obj, offset, newValue);
429                    }
430                }
431
432                public void lazySet(T obj, long newValue) {
433                    set(obj, newValue);
434                }
435
436                public long get(T obj) {
437                    if (obj == null || obj.getClass() != tclass
438                            || cclass != null)
439                        fullCheck(obj);
440                    synchronized (this ) {
441                        return unsafe.getLong(obj, offset);
442                    }
443                }
444
445                private void ensureProtectedAccess(T obj) {
446                    if (cclass.isInstance(obj)) {
447                        return;
448                    }
449                    throw new RuntimeException(
450                            new IllegalAccessException(
451                                    "Class "
452                                            + cclass.getName()
453                                            + " can not access a protected member of class "
454                                            + tclass.getName()
455                                            + " using an instance of "
456                                            + obj.getClass().getName()));
457                }
458            }
459        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.