OSDN Git Service

a0d9d0ad6657f69d90b475b85995b940d1434e6f
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / ThreadLocal.java
1 /* java.lang.ThreadLocal
2    Copyright (C) 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 As a special exception, if you link this library with other files to
22 produce an executable, this library does not by itself cause the
23 resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why the
25 executable file might be covered by the GNU General Public License. */
26
27 package java.lang;
28
29 import java.util.Map;
30 import java.util.WeakHashMap;
31
32 /**
33  * ThreadLocal objects have a different state associated with every
34  * Thread that accesses them. Every access to the ThreadLocal object
35  * (through the <code>get()</code> and <code>set()</code> methods)
36  * only affects the state of the object as seen by the currently
37  * executing Thread.
38  * <p>
39  * The first time a ThreadLocal object is accessed on a particular
40  * Thread (and no state is associated with that Thread yet)
41  * the state for that Thread is set by executing the method
42  * <code>initialValue()</code>.
43  * <p>
44  * An example how you can use this:
45  * <pre>
46  * class Connection {
47  *     private static ThreadLocal owner = new ThreadLocal() {
48  *        public Object initialValue() {
49  *            return("nobody");
50  *        }
51  *     };
52  * ...
53  * }
54  * </pre>
55  * Now all instances of connection can see who the owner of the currently
56  * executing Thread is by calling <code>owner.get()</code>. By default any
57  * Thread would be associated with 'nobody'. But the Connection object could
58  * offer a method that changes the owner associated with the Thread on
59  * which the method was called by calling <code>owner.put("somebody")</code>.
60  * (Such an owner changing method should then be guarded by security checks.)
61  * <p>
62  * When a Thread is garbage collected all references to values of
63  * the ThreadLocal objects associated with that Thread are removed.
64  *
65  * @since 1.2
66  * @author Mark Wielaard (mark@klomp.org)
67  */
68 public class ThreadLocal {
69         
70         /**
71          * Trivial container to wrap the stored values.
72          * Needed to see if the value is null or not yet set.
73          * If it is not yet set we must call intialValue() once.
74          * Package local so InheritableThreadLocal can see it.
75          */
76         final static class Value {
77                 final Object value;
78                 
79                 Value(Object value) {
80                         this.value = value;
81                 }
82                 
83                 Object getValue() {
84                         return value;
85                 }
86         }
87         
88         /**
89          * Maps Threads to Values. Uses a WeakHashMap so if a Thread is garbage
90          * collected the reference to the Value will disappear. Only the
91          * <code>set(Thread, Value)</code> and <code>get(Thread)</code> methods
92          * access it. Since this can happen from multiple Threads simultaniously
93          * those methods are synchronized.
94          */
95         private final Map valueMap = new WeakHashMap();
96         
97         /**
98          * Creates a ThreadLocal object without associating any value to it
99          * yet.
100          */
101         public ThreadLocal() {
102         }
103         
104         /**
105          * Gets the value associated with the ThreadLocal object for the
106          * currently executing Thread. If there is no value is associated
107          * with this Thread yet then the valued returned by the
108          * <code>initialValue()</code> method is assosiated with this Thread
109          * and returned.
110          */
111         public Object get() {
112                 Thread currentThread = Thread.currentThread();
113                 Value v = get(currentThread);
114                 if (v == null) {
115                         v = new Value(initialValue());
116                         set(currentThread, v);
117                 }
118                 return v.getValue();
119         }
120         
121         /**
122          * Gets the Value of this ThreadLocal for a particular Thread.
123          * It is synchronized so the <code>set(Thread, Value)</code> method cannot
124          * simultaniously modify the </code>valueMap</code> from another thread.
125          * Package local so InheritableThreadLocal can access it when a new child
126          * Thread inherits values from its parent Thread.
127          */
128         synchronized final Value get(Thread thread) {
129                 return (Value)valueMap.get(thread);
130         }
131         
132         /**
133          * Sets the value associated with the ThreadLocal object for the
134          * currently executing Thread. This overrides any existing value
135          * associated with the current Thread and does not call the
136          * <code>initialValue()</code> method, even if this is the first
137          * time this Thread accesses this ThreadLocal.
138          */
139         public void set(Object value) {
140                 Thread currentThread = Thread.currentThread();
141                 Value v = new Value(value);
142                 set(currentThread, v);
143         }
144         
145         /**
146          * Sets the Value for this ThreadLocal for a particular Thread.
147          * It is synchronized so the <code>get(Thread)</code> method cannot
148          * simultaniously read the </code>valueMap</code> from another thread.
149          * Package local so InheritableThreadLocal can access it when a new child
150          * Thread inherits values from its parent Thread.
151          */
152         synchronized final void set(Thread thread, Value value) {
153                 valueMap.put(thread, value);
154         }
155         
156         /**
157          * Called when <code>get()</code> is called and no state is associated
158          * with the currently executing Thread yet.
159          * <p>
160          * The default implementation returns <code>null</code>.
161          */
162         protected Object initialValue() {
163                 return null;
164         }
165 }