use of io.netty.util.concurrent.FastThreadLocalThread in project netty by netty.
the class PooledByteBufAllocatorTest method testThreadCacheDestroyedByThreadDeathWatcher.
// The ThreadDeathWatcher sleeps 1s, give it double that time.
@Test(timeout = 2000)
public void testThreadCacheDestroyedByThreadDeathWatcher() {
int numArenas = 11;
final PooledByteBufAllocator allocator = new PooledByteBufAllocator(numArenas, numArenas, 8192, 1);
final AtomicBoolean threadCachesCreated = new AtomicBoolean(true);
for (int i = 0; i < numArenas; i++) {
new FastThreadLocalThread(new Runnable() {
@Override
public void run() {
ByteBuf buf = allocator.newHeapBuffer(1024, 1024);
for (int i = 0; i < buf.capacity(); i++) {
buf.writeByte(0);
}
// thread caches without any of them ever having been initialized.
if (allocator.metric().numThreadLocalCaches() == 0) {
threadCachesCreated.set(false);
}
buf.release();
}
}).start();
}
// Wait for the ThreadDeathWatcher to have destroyed all thread caches
while (allocator.metric().numThreadLocalCaches() > 0) {
LockSupport.parkNanos(MILLISECONDS.toNanos(100));
}
assertTrue(threadCachesCreated.get());
}
use of io.netty.util.concurrent.FastThreadLocalThread in project turbo-rpc by hank-whu.
the class AttachmentThreadUtils method put.
/**
* @param index
* 通过 {@link #nextVarIndex()} 获得
*
* @param value
*/
public static <T> void put(int index, T value) {
Thread currentThread = Thread.currentThread();
if (currentThread instanceof FastThreadLocalThread) {
// 很快,1.5x ThreadLocal性能
FastThreadLocalThread fastThread = (FastThreadLocalThread) currentThread;
InternalThreadLocalMap threadLocalMap = fastThread.threadLocalMap();
if (threadLocalMap == null) {
// 会自动赋值的
threadLocalMap = InternalThreadLocalMap.get();
}
threadLocalMap.setIndexedVariable(index, value);
return;
}
if (currentThread instanceof AttachmentThread) {
// 很快,1.5x ThreadLocal性能
AttachmentThread attachmentThread = (AttachmentThread) currentThread;
attachmentThread.put(index, value);
return;
}
long currentThreadId = currentThread.getId();
if (currentThreadId < 1024L * 16L) {
// 跟直接使用ThreadLocal相同的性能
IntToObjectArrayMap<Object> varMap = threadAttachmentMap.get((int) currentThreadId);
if (varMap == null) {
varMap = // 会自动赋值的
threadAttachmentMap.getOrUpdate((int) currentThreadId, () -> new IntToObjectArrayMap<>());
}
varMap.put(index, value);
return;
}
{
// 很慢,0.7x ThreadLocal性能
IntToObjectArrayMap<Object> varMap = SLOW_THREAD_LOCAL_HOLDER.get();
varMap.put(index, value);
return;
}
}
use of io.netty.util.concurrent.FastThreadLocalThread in project cassandra by apache.
the class NamedThreadFactory method createThread.
public static Thread createThread(ThreadGroup threadGroup, Runnable runnable, String name, boolean daemon) {
Thread thread = new FastThreadLocalThread(threadGroup, threadLocalDeallocator(runnable), name);
thread.setDaemon(daemon);
return thread;
}
use of io.netty.util.concurrent.FastThreadLocalThread in project netty by netty.
the class PooledByteBufAllocatorTest method createNewThreadCache.
private static ThreadCache createNewThreadCache(final PooledByteBufAllocator allocator) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final CountDownLatch cacheLatch = new CountDownLatch(1);
final Thread t = new FastThreadLocalThread(new Runnable() {
@Override
public void run() {
ByteBuf buf = allocator.newHeapBuffer(1024, 1024);
// Countdown the latch after we allocated a buffer. At this point the cache must exists.
cacheLatch.countDown();
buf.writeZero(buf.capacity());
try {
latch.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
buf.release();
FastThreadLocal.removeAll();
}
});
t.start();
// Wait until we allocated a buffer and so be sure the thread was started and the cache exists.
cacheLatch.await();
return new ThreadCache() {
@Override
public void destroy() throws InterruptedException {
latch.countDown();
t.join();
}
};
}
use of io.netty.util.concurrent.FastThreadLocalThread in project turbo-rpc by hank-whu.
the class AttachmentThreadUtils method getOrUpdate.
/**
* @param index
* 通过 {@link #nextVarIndex()} 获得
*
* @param producer
* 尽量使用final常量以获得更好的性能
*
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getOrUpdate(int index, Supplier<T> producer) {
Thread currentThread = Thread.currentThread();
if (currentThread instanceof FastThreadLocalThread) {
// 很快,1.5x ThreadLocal性能
FastThreadLocalThread fastThread = (FastThreadLocalThread) currentThread;
InternalThreadLocalMap threadLocalMap = fastThread.threadLocalMap();
if (threadLocalMap == null) {
// 会自动赋值的
threadLocalMap = InternalThreadLocalMap.get();
}
Object obj = threadLocalMap.indexedVariable(index);
if (obj != InternalThreadLocalMap.UNSET) {
return (T) obj;
}
obj = producer.get();
threadLocalMap.setIndexedVariable(index, obj);
return (T) obj;
}
if (currentThread instanceof AttachmentThread) {
// 很快,1.5x ThreadLocal性能
AttachmentThread attachmentThread = (AttachmentThread) currentThread;
T result = attachmentThread.get(index);
if (result != null) {
return result;
} else {
return attachmentThread.getOrUpdate(index, producer);
}
}
long currentThreadId = currentThread.getId();
if (currentThreadId < 1024L * 16L) {
// 跟直接使用ThreadLocal相同的性能
IntToObjectArrayMap<Object> varMap = threadAttachmentMap.get((int) currentThreadId);
if (varMap == null) {
varMap = // 会自动赋值的
threadAttachmentMap.getOrUpdate((int) currentThreadId, () -> new IntToObjectArrayMap<>());
}
Object obj = varMap.get(index);
if (obj != null) {
return (T) obj;
} else {
return (T) varMap.getOrUpdate(index, (Supplier<Object>) producer);
}
}
{
// 很慢,0.7x ThreadLocal性能
IntToObjectArrayMap<Object> varMap = SLOW_THREAD_LOCAL_HOLDER.get();
Object obj = varMap.get(index);
if (obj != null) {
return (T) obj;
} else {
return (T) varMap.getOrUpdate(index, (Supplier<Object>) producer);
}
}
}
Aggregations