1 |
/* ThreadLocal -- a variable with a unique value per thread |
/* ThreadLocal -- a variable with a unique value per thread |
2 |
Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc. |
Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
82 |
* @since 1.2 |
* @since 1.2 |
83 |
* @status updated to 1.4 |
* @status updated to 1.4 |
84 |
*/ |
*/ |
85 |
public class ThreadLocal |
public class ThreadLocal<T> |
86 |
{ |
{ |
87 |
/** |
/** |
88 |
* Placeholder to distinguish between uninitialized and null set by the |
* Placeholder to distinguish between uninitialized and null set by the |
93 |
|
|
94 |
/** |
/** |
95 |
* The stored value. Package visible for use by InheritableThreadLocal. */ |
* The stored value. Package visible for use by InheritableThreadLocal. */ |
96 |
Object value; |
T value; |
97 |
|
|
98 |
/** |
/** |
99 |
* Maps Threads to values. Uses a WeakHashMap so if a Thread is garbage |
* Maps Threads to values. Uses a WeakHashMap so if a Thread is garbage |
100 |
* collected the reference to the Value will disappear. A null value means |
* collected the reference to the Value will disappear. A null value means |
102 |
* <code>set(Thread, Object)</code> and <code>get(Thread)</code> methods |
* <code>set(Thread, Object)</code> and <code>get(Thread)</code> methods |
103 |
* access it. Package visible for use by InheritableThreadLocal. |
* access it. Package visible for use by InheritableThreadLocal. |
104 |
*/ |
*/ |
105 |
final Map valueMap = Collections.synchronizedMap(new WeakHashMap()); |
final Map<Thread, T> valueMap |
106 |
|
= Collections.synchronizedMap(new WeakHashMap<Thread, T>()); |
107 |
|
|
108 |
/** |
/** |
109 |
* Creates a ThreadLocal object without associating any value to it yet. |
* Creates a ThreadLocal object without associating any value to it yet. |
110 |
*/ |
*/ |
120 |
* |
* |
121 |
* @return the initial value of the variable in this thread |
* @return the initial value of the variable in this thread |
122 |
*/ |
*/ |
123 |
protected Object initialValue() |
protected T initialValue() |
124 |
{ |
{ |
125 |
return null; |
return null; |
126 |
} |
} |
133 |
* |
* |
134 |
* @return the value of the variable in this thread |
* @return the value of the variable in this thread |
135 |
*/ |
*/ |
136 |
public Object get() |
public T get() |
137 |
{ |
{ |
138 |
Thread currentThread = Thread.currentThread(); |
Thread currentThread = Thread.currentThread(); |
139 |
// Note that we don't have to synchronize, as only this thread will |
// Note that we don't have to synchronize, as only this thread will |
140 |
// ever modify the returned value and valueMap is a synchronizedMap. |
// ever modify the returned value and valueMap is a synchronizedMap. |
141 |
Object value = valueMap.get(currentThread); |
T value = valueMap.get(currentThread); |
142 |
if (value == null) |
if (value == null) |
143 |
{ |
{ |
144 |
value = initialValue(); |
value = initialValue(); |
145 |
valueMap.put(currentThread, value == null ? NULL : value); |
valueMap.put(currentThread, value == null ? (T) NULL : value); |
146 |
} |
} |
147 |
return value == NULL ? null : value; |
return value == (T) NULL ? null : value; |
148 |
} |
} |
149 |
|
|
150 |
/** |
/** |
155 |
* |
* |
156 |
* @param value the value to set this thread's view of the variable to |
* @param value the value to set this thread's view of the variable to |
157 |
*/ |
*/ |
158 |
public void set(Object value) |
public void set(T value) |
159 |
{ |
{ |
160 |
// Note that we don't have to synchronize, as only this thread will |
// Note that we don't have to synchronize, as only this thread will |
161 |
// ever modify the returned value and valueMap is a synchronizedMap. |
// ever modify the returned value and valueMap is a synchronizedMap. |
162 |
valueMap.put(Thread.currentThread(), value == null ? NULL : value); |
valueMap.put(Thread.currentThread(), value == null ? (T) NULL : value); |
163 |
} |
} |
164 |
} |
} |