From aac560ac261e7a2fde599c6b162f99acd3348fe7 Mon Sep 17 00:00:00 2001 From: Alexandre Petit-Bianco Date: Tue, 10 Jul 2001 17:47:37 -0700 Subject: Makefile.am: Added `java/lang/ThreadLocal.java'. libjava: 2001-07-10 Alexandre Petit-Bianco * Makefile.am: Added `java/lang/ThreadLocal.java'. * Makefile.in: Regenerate. * java/lang/ThreadLocal.java: Initial import. libjava/testsuite: 2001-07-10 Alexandre Petit-Bianco * libjava.lang/TLtest.java: New file. * libjava.lang/TLtest.out: New file. (http://gcc.gnu.org/ml/java-patches/2001-q3/msg00042.html ) From-SVN: r43915 --- libjava/java/lang/ThreadLocal.java | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 libjava/java/lang/ThreadLocal.java (limited to 'libjava/java/lang/ThreadLocal.java') diff --git a/libjava/java/lang/ThreadLocal.java b/libjava/java/lang/ThreadLocal.java new file mode 100644 index 0000000..a0d9d0a --- /dev/null +++ b/libjava/java/lang/ThreadLocal.java @@ -0,0 +1,165 @@ +/* java.lang.ThreadLocal + Copyright (C) 2000 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath 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 for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + +package java.lang; + +import java.util.Map; +import java.util.WeakHashMap; + +/** + * ThreadLocal objects have a different state associated with every + * Thread that accesses them. Every access to the ThreadLocal object + * (through the get() and set() methods) + * only affects the state of the object as seen by the currently + * executing Thread. + *

+ * The first time a ThreadLocal object is accessed on a particular + * Thread (and no state is associated with that Thread yet) + * the state for that Thread is set by executing the method + * initialValue(). + *

+ * An example how you can use this: + *

+ * class Connection {
+ *     private static ThreadLocal owner = new ThreadLocal() {
+ *        public Object initialValue() {
+ *            return("nobody");
+ *        }
+ *     };
+ * ...
+ * }
+ * 
+ * Now all instances of connection can see who the owner of the currently + * executing Thread is by calling owner.get(). By default any + * Thread would be associated with 'nobody'. But the Connection object could + * offer a method that changes the owner associated with the Thread on + * which the method was called by calling owner.put("somebody"). + * (Such an owner changing method should then be guarded by security checks.) + *

+ * When a Thread is garbage collected all references to values of + * the ThreadLocal objects associated with that Thread are removed. + * + * @since 1.2 + * @author Mark Wielaard (mark@klomp.org) + */ +public class ThreadLocal { + + /** + * Trivial container to wrap the stored values. + * Needed to see if the value is null or not yet set. + * If it is not yet set we must call intialValue() once. + * Package local so InheritableThreadLocal can see it. + */ + final static class Value { + final Object value; + + Value(Object value) { + this.value = value; + } + + Object getValue() { + return value; + } + } + + /** + * Maps Threads to Values. Uses a WeakHashMap so if a Thread is garbage + * collected the reference to the Value will disappear. Only the + * set(Thread, Value) and get(Thread) methods + * access it. Since this can happen from multiple Threads simultaniously + * those methods are synchronized. + */ + private final Map valueMap = new WeakHashMap(); + + /** + * Creates a ThreadLocal object without associating any value to it + * yet. + */ + public ThreadLocal() { + } + + /** + * Gets the value associated with the ThreadLocal object for the + * currently executing Thread. If there is no value is associated + * with this Thread yet then the valued returned by the + * initialValue() method is assosiated with this Thread + * and returned. + */ + public Object get() { + Thread currentThread = Thread.currentThread(); + Value v = get(currentThread); + if (v == null) { + v = new Value(initialValue()); + set(currentThread, v); + } + return v.getValue(); + } + + /** + * Gets the Value of this ThreadLocal for a particular Thread. + * It is synchronized so the set(Thread, Value) method cannot + * simultaniously modify the valueMap from another thread. + * Package local so InheritableThreadLocal can access it when a new child + * Thread inherits values from its parent Thread. + */ + synchronized final Value get(Thread thread) { + return (Value)valueMap.get(thread); + } + + /** + * Sets the value associated with the ThreadLocal object for the + * currently executing Thread. This overrides any existing value + * associated with the current Thread and does not call the + * initialValue() method, even if this is the first + * time this Thread accesses this ThreadLocal. + */ + public void set(Object value) { + Thread currentThread = Thread.currentThread(); + Value v = new Value(value); + set(currentThread, v); + } + + /** + * Sets the Value for this ThreadLocal for a particular Thread. + * It is synchronized so the get(Thread) method cannot + * simultaniously read the valueMap from another thread. + * Package local so InheritableThreadLocal can access it when a new child + * Thread inherits values from its parent Thread. + */ + synchronized final void set(Thread thread, Value value) { + valueMap.put(thread, value); + } + + /** + * Called when get() is called and no state is associated + * with the currently executing Thread yet. + *

+ * The default implementation returns null. + */ + protected Object initialValue() { + return null; + } +} -- cgit v1.1