⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threadlocal.java

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * @(#)ThreadLocal.java	1.23 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package java.lang;import java.lang.ref.*;/** * This class provides thread-local variables.  These variables differ from * their normal counterparts in that each thread that accesses one (via its * <tt>get</tt> or <tt>set</tt> method) has its own, independently initialized * copy of the variable.  <tt>ThreadLocal</tt> instances are typically private * static fields in classes that wish to associate state with a thread (e.g., * a user ID or Transaction ID). * * <p>For example, in the class below, the private static <tt>ThreadLocal</tt> * instance (<tt>serialNum</tt>) maintains a "serial number" for each thread * that invokes the class's static <tt>SerialNum.get()</tt> method, which * returns the current thread's serial number.  (A thread's serial number is * assigned the first time it invokes <tt>SerialNum.get()</tt>, and remains * unchanged on subsequent calls.) * <pre> * public class SerialNum { *     // The next serial number to be assigned *     private static int nextSerialNum = 0; *  *     private static ThreadLocal serialNum = new ThreadLocal() { *         protected synchronized Object initialValue() { *             return new Integer(nextSerialNum++); *         } *     }; *  *     public static int get() { *         return ((Integer) (serialNum.get())).intValue(); *     } * } * </pre> *  * <p>Each thread holds an implicit reference to its copy of a thread-local * variable as long as the thread is alive and the <tt>ThreadLocal</tt> * instance is accessible; after a thread goes away, all of its copies of * thread-local instances are subject to garbage collection (unless other * references to these copies exist).  * * @author  Josh Bloch and Doug Lea * @version 1.23, 10/10/06 * @since   1.2 */public class ThreadLocal {    /**      * ThreadLocals rely on per-thread hash maps attached to each thread     * (Thread.threadLocals and inheritableThreadLocals).  The ThreadLocal     * objects act as keys, searched via threadLocalHashCode.  This is a     * custom hash code (useful only within ThreadLocalMaps) that eliminates     * collisions in the common case where consecutively constructed     * ThreadLocals are used by the same threads, while remaining well-behaved     * in less common cases.     */    private final int threadLocalHashCode = nextHashCode();    /**     * The next hash code to be given out. Accessed only by like-named method.     */    private static int nextHashCode = 0;    /**     * The difference between successively generated hash codes - turns     * implicit sequential thread-local IDs into near-optimally spread     * multiplicative hash values for power-of-two-sized tables.     */    private static final int HASH_INCREMENT = 0x61c88647;    /**     * Compute the next hash code. The static synchronization used here     * should not be a performance bottleneck. When ThreadLocals are     * generated in different threads at a fast enough rate to regularly     * contend on this lock, memory contention is by far a more serious     * problem than lock contention.     */    private static synchronized int nextHashCode() {         int h = nextHashCode;        nextHashCode = h + HASH_INCREMENT;        return h;    }    /**     * Returns the current thread's initial value for this thread-local     * variable.  This method will be invoked at most once per accessing     * thread for each thread-local, the first time the thread accesses the     * variable with the {@link #get()} method.  The <tt>initialValue</tt>     * method will not be invoked in a thread if the thread invokes the {@link     * #set(Object)} method prior to the <tt>get</tt> method.     *     * <p>This implementation simply returns <tt>null</tt>; if the programmer     * desires thread-local variables to be initialized to some value other     * than <tt>null</tt>, <tt>ThreadLocal</tt> must be subclassed, and this     * method overridden.  Typically, an anonymous inner class will be used.     * Typical implementations of <tt>initialValue</tt> will invoke an     * appropriate constructor and return the newly constructed object.     *     * @return the initial value for this thread-local     */    protected Object initialValue() {        return null;    }    /**     * Returns the value in the current thread's copy of this thread-local     * variable.  Creates and initializes the copy if this is the first time     * the thread has called this method.     *     * @return the current thread's value of this thread-local     */    public Object get() {        Thread t = Thread.currentThread();        ThreadLocalMap map = getMap(t);        if (map != null)             return map.get(this);        // Maps are constructed lazily.  if the map for this thread        // doesn't exist, create it, with this ThreadLocal and its        // initial value as its only entry.        Object value = initialValue();        createMap(t, value);        return value;    }    /**     * Sets the current thread's copy of this thread-local variable     * to the specified value.  Many applications will have no need for     * this functionality, relying solely on the {@link #initialValue()}     * method to set the values of thread-locals.     *     * @param value the value to be stored in the current threads' copy of     *	      this thread-local.     */    public void set(Object value) {        Thread t = Thread.currentThread();        ThreadLocalMap map = getMap(t);        if (map != null)             map.set(this, value);        else            createMap(t, value);    }    /*     * Removes the value for this ThreadLocal.     THIS METHOD COULD BE UNCOMMENTED TO ADD IT TO THE PUBLIC API IF THAT     IS THOUGHT TO DESIRABLE AT SOME POINT.     public void remove() {         ThreadLocalMap m = getMap(Thread.currentThread());         if (m != null)              m.remove(this);     }     */    /**     * Get the map associated with a ThreadLocal. Overridden in     * InheritableThreadLocal.     *     * @param  t the current thread     * @return the map     */    ThreadLocalMap getMap(Thread t) {        return t.threadLocals;    }    /**     * Create the map associated with a ThreadLocal. Overridden in     * InheritableThreadLocal.     *     * @param t the current thread     * @param firstValue value for the initial entry of the map     * @param map the map to store.     */    void createMap(Thread t, Object firstValue) {        t.threadLocals = new ThreadLocalMap(this, firstValue);    }    /**     * Factory method to create map of inherited thread locals.     * Designed to be called only from Thread constructor.     *     * @param  parentMap the map associated with parent thread     * @return a map containing the parent's inheritable bindings     */    static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {        return new ThreadLocalMap(parentMap);    }    /**     * Method childValue is visibly defined in subclass     * InheritableThreadLocal, but is internally defined here for the     * sake of providing createInheritedMap factory method without     * needing to subclass the map class in InheritableThreadLocal.     * This technique is preferable to the alternative of embedding     * instanceof tests in methods.     */    Object childValue(Object parentValue) {        throw new UnsupportedOperationException();    }    /**     * ThreadLocalMap is a customized hash map suitable only for     * maintaining thread local values. No operations are exported     * outside of the ThreadLocal class. The class is package private to     * allow declaration of fields in class Thread.  To help deal with     * very large and long-lived usages, the hash table entries use     * WeakReferences for keys. However, since reference queues are not     * used, stale entries are guaranteed to be removed only when     * the table starts running out of space.     */    static class ThreadLocalMap {        /**         * The entries in this hash map extend WeakReference, using         * its main ref field as the key (which is always a         * ThreadLocal object).  Note that null keys (i.e. entry.get()         * == null) mean that the key is no longer referenced, so the         * entry can be expunged from table.  Such entries are referred to         * as "stale entries" in the code that follows.         */         private static class Entry extends WeakReference {            /** The value associated with this ThreadLocal. */            private Object value;            private Entry(ThreadLocal k, Object v) {                super(k);                value = v;            }        }        /**         * The initial capacity -- MUST be a power of two.         */        private static final int INITIAL_CAPACITY = 16;        /**         * The table, resized as necessary.          * table.length MUST always be a power of two.         */        private Entry[] table;        /**         * The number of entries in the table.           */        private int size = 0;        /**         * The next size value at which to resize.          */        private int threshold;        /**         * Set the resize threshold to maintain at worst a 2/3 load factor.         */        private void setThreshold(int len) {            threshold = len * 2 / 3;        }        /**         * Increment i modulo len.         */        private static int nextIndex(int i, int len) {            return ((i + 1 < len) ? i + 1 : 0);        }        /**         * Decrement i modulo len.         */        private static int prevIndex(int i, int len) {            return ((i - 1 >= 0) ? i - 1 : len - 1);        }        /**         * Construct a new map initially containing (firstKey, firstValue).         * ThreadLocalMaps are constructed lazily, so we only create         * one when we have at least one entry to put in it.         */        ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {            table = new Entry[INITIAL_CAPACITY];            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);            table[i] = new Entry(firstKey, firstValue);            size = 1;            setThreshold(INITIAL_CAPACITY);        }        /**         * Construct a new map including all Inheritable ThreadLocals         * from given parent map. Called only by createInheritedMap.         *         * @param parentMap the map associated with parent thread.         */        private ThreadLocalMap(ThreadLocalMap parentMap) {            Entry[] parentTable = parentMap.table;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -