1 |
/* InheritableThreadLocal -- a ThreadLocal which inherits values across threads |
/* InheritableThreadLocal -- a ThreadLocal which inherits values across threads |
2 |
Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. |
Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
61 |
* @since 1.2 |
* @since 1.2 |
62 |
* @status updated to 1.4 |
* @status updated to 1.4 |
63 |
*/ |
*/ |
64 |
public class InheritableThreadLocal extends ThreadLocal |
public class InheritableThreadLocal<T> extends ThreadLocal<T> |
65 |
{ |
{ |
66 |
/** |
/** |
67 |
* Maps Threads to a List of InheritableThreadLocals (the heritage of that |
* Maps Threads to a List of InheritableThreadLocals (the heritage of that |
69 |
* List can be collected, too. Maps to a list in case the user overrides |
* List can be collected, too. Maps to a list in case the user overrides |
70 |
* equals. |
* equals. |
71 |
*/ |
*/ |
72 |
private static final Map threadMap |
private static final Map threadMap<Thread, ArrayList<InheritableThreadLocals<T>>> |
73 |
= Collections.synchronizedMap(new WeakHashMap()); |
= Collections.synchronizedMap(new WeakHashMap<Thread, ArrayList<InheritableThreadLocals<T>>>()); |
74 |
|
|
75 |
/** |
/** |
76 |
* Creates a new InheritableThreadLocal that has no values associated |
* Creates a new InheritableThreadLocal that has no values associated |
81 |
Thread currentThread = Thread.currentThread(); |
Thread currentThread = Thread.currentThread(); |
82 |
// 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 |
83 |
// ever modify the returned heritage and threadMap is a synchronizedMap. |
// ever modify the returned heritage and threadMap is a synchronizedMap. |
84 |
List heritage = (List) threadMap.get(currentThread); |
List<InheritableThreadLocal<T>> heritage = threadMap.get(currentThread); |
85 |
if (heritage == null) |
if (heritage == null) |
86 |
{ |
{ |
87 |
heritage = new ArrayList(); |
heritage = new ArrayList<InheritableThreadLocal<T>>(); |
88 |
threadMap.put(currentThread, heritage); |
threadMap.put(currentThread, heritage); |
89 |
} |
} |
90 |
heritage.add(this); |
heritage.add(this); |
99 |
* the moment of creation of the child |
* the moment of creation of the child |
100 |
* @return the initial value for the child thread |
* @return the initial value for the child thread |
101 |
*/ |
*/ |
102 |
protected Object childValue(Object parentValue) |
protected T childValue(T parentValue) |
103 |
{ |
{ |
104 |
return parentValue; |
return parentValue; |
105 |
} |
} |
118 |
Thread parentThread = Thread.currentThread(); |
Thread parentThread = Thread.currentThread(); |
119 |
// 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 |
120 |
// ever modify the returned heritage and threadMap is a synchronizedMap. |
// ever modify the returned heritage and threadMap is a synchronizedMap. |
121 |
ArrayList heritage = (ArrayList) threadMap.get(parentThread); |
ArrayList<InheritableThreadLocal<T>> heritage |
122 |
|
= threadMap.get(parentThread); |
123 |
if (heritage != null) |
if (heritage != null) |
124 |
{ |
{ |
125 |
threadMap.put(childThread, heritage.clone()); |
threadMap.put(childThread, |
126 |
|
(ArrayList<InheritableThreadLocal<T>>) heritage.clone()); |
127 |
// Perform the inheritance. |
// Perform the inheritance. |
128 |
Iterator it = heritage.iterator(); |
Iterator<InheritableThreadLocal<T>> it = heritage.iterator(); |
129 |
int i = heritage.size(); |
int i = heritage.size(); |
130 |
while (--i >= 0) |
while (--i >= 0) |
131 |
{ |
{ |
132 |
InheritableThreadLocal local = (InheritableThreadLocal) it.next(); |
InheritableThreadLocal<T> local = it.next(); |
133 |
Object parentValue = local.valueMap.get(parentThread); |
T parentValue = local.valueMap.get(parentThread); |
134 |
if (parentValue != null) |
if (parentValue != null) |
135 |
{ |
{ |
136 |
Object childValue = local.childValue(parentValue == NULL |
T childValue = local.childValue(parentValue == (T) NULL |
137 |
? null : parentValue); |
? null : parentValue); |
138 |
local.valueMap.put(childThread, (childValue == null |
local.valueMap.put(childThread, (childValue == null |
139 |
? NULL : parentValue)); |
? (T) NULL : parentValue)); |
140 |
} |
} |
141 |
} |
} |
142 |
} |
} |