Ensure ObjectCleaner will also be used when FastThreadLocal.set is used.
Motivation: e329ca1 introduced the user of ObjectCleaner in FastThreadLocal but we missed the case to register our cleaner task if FastThreadLocal.set was called only. Modifications: - Use ObjectCleaner also when FastThreadLocal.set is used. - Add test case. Result: ObjectCleaner is always used.
This commit is contained in:
parent
6b033c51a5
commit
e004b4a354
@ -134,13 +134,18 @@ public class FastThreadLocal<V> {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final V get() {
|
public final V get() {
|
||||||
final InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get();
|
InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get();
|
||||||
Object v = threadLocalMap.indexedVariable(index);
|
Object v = threadLocalMap.indexedVariable(index);
|
||||||
if (v != InternalThreadLocalMap.UNSET) {
|
if (v != InternalThreadLocalMap.UNSET) {
|
||||||
return (V) v;
|
return (V) v;
|
||||||
}
|
}
|
||||||
|
|
||||||
V value = initialize(threadLocalMap);
|
V value = initialize(threadLocalMap);
|
||||||
|
registerCleaner(threadLocalMap);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerCleaner(final InternalThreadLocalMap threadLocalMap) {
|
||||||
Thread current = Thread.currentThread();
|
Thread current = Thread.currentThread();
|
||||||
if (!FastThreadLocalThread.willCleanupFastThreadLocals(current)) {
|
if (!FastThreadLocalThread.willCleanupFastThreadLocals(current)) {
|
||||||
// We will need to ensure we will trigger remove(InternalThreadLocalMap) so everything will be released
|
// We will need to ensure we will trigger remove(InternalThreadLocalMap) so everything will be released
|
||||||
@ -155,7 +160,6 @@ public class FastThreadLocal<V> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,7 +194,13 @@ public class FastThreadLocal<V> {
|
|||||||
*/
|
*/
|
||||||
public final void set(V value) {
|
public final void set(V value) {
|
||||||
if (value != InternalThreadLocalMap.UNSET) {
|
if (value != InternalThreadLocalMap.UNSET) {
|
||||||
set(InternalThreadLocalMap.get(), value);
|
InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get();
|
||||||
|
boolean alreadySet = threadLocalMap.isIndexedVariableSet(index);
|
||||||
|
set(threadLocalMap, value);
|
||||||
|
|
||||||
|
if (!alreadySet) {
|
||||||
|
registerCleaner(threadLocalMap);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
|
@ -77,16 +77,26 @@ public class FastThreadLocalTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 4000)
|
@Test(timeout = 4000)
|
||||||
public void testOnRemoveCalledForFastThreadLocal() throws Exception {
|
public void testOnRemoveCalledForFastThreadLocalGet() throws Exception {
|
||||||
testOnRemoveCalled(true);
|
testOnRemoveCalled(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(timeout = 4000)
|
@Test(timeout = 4000)
|
||||||
public void testOnRemoveCalledForNonFastThreadLocal() throws Exception {
|
public void testOnRemoveCalledForNonFastThreadLocalGet() throws Exception {
|
||||||
testOnRemoveCalled(false);
|
testOnRemoveCalled(false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testOnRemoveCalled(boolean fastThreadLocal) throws Exception {
|
@Test(timeout = 4000)
|
||||||
|
public void testOnRemoveCalledForFastThreadLocalSet() throws Exception {
|
||||||
|
testOnRemoveCalled(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 4000)
|
||||||
|
public void testOnRemoveCalledForNonFastThreadLocalSet() throws Exception {
|
||||||
|
testOnRemoveCalled(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testOnRemoveCalled(boolean fastThreadLocal, final boolean callGet) throws Exception {
|
||||||
|
|
||||||
final TestFastThreadLocal threadLocal = new TestFastThreadLocal();
|
final TestFastThreadLocal threadLocal = new TestFastThreadLocal();
|
||||||
final TestFastThreadLocal threadLocal2 = new TestFastThreadLocal();
|
final TestFastThreadLocal threadLocal2 = new TestFastThreadLocal();
|
||||||
@ -94,8 +104,13 @@ public class FastThreadLocalTest {
|
|||||||
Runnable runnable = new Runnable() {
|
Runnable runnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
assertEquals(Thread.currentThread().getName(), threadLocal.get());
|
if (callGet) {
|
||||||
assertEquals(Thread.currentThread().getName(), threadLocal2.get());
|
assertEquals(Thread.currentThread().getName(), threadLocal.get());
|
||||||
|
assertEquals(Thread.currentThread().getName(), threadLocal2.get());
|
||||||
|
} else {
|
||||||
|
threadLocal.set(Thread.currentThread().getName());
|
||||||
|
threadLocal2.set(Thread.currentThread().getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Thread thread = fastThreadLocal ? new FastThreadLocalThread(runnable) : new Thread(runnable);
|
Thread thread = fastThreadLocal ? new FastThreadLocalThread(runnable) : new Thread(runnable);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user