Java tutorial
/* * Copyright 1999-2004 Alibaba.com All right reserved. This software is the confidential and proprietary information of * Alibaba.com ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only * in accordance with the terms of the license agreement you entered into with Alibaba.com. */ package com.agapple.asyncload.impl.pool; import java.lang.reflect.Field; import java.util.concurrent.BlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.springframework.util.ReflectionUtils; /** * J.U.CThreadPoolExecutor? * * <pre> * 1. newTaskFor{@linkplain AsyncLoadFuture} * 2. PoolWorker?caller ThreadthreadLocal? * a. Workerpool??ThreadLocal???task???ThreadLocalWorker<=Caller Thread * b. ????????ThreadLocal? * </pre> * * @author jianghang 2011-3-28 ?09:56:32 */ public class AsyncLoadThreadPool extends ThreadPoolExecutor { private static final Field threadLocalField = ReflectionUtils.findField(Thread.class, "threadLocals"); private static final Field inheritableThreadLocalField = ReflectionUtils.findField(Thread.class, "inheritableThreadLocals"); static { // accessible ReflectionUtils.makeAccessible(threadLocalField); ReflectionUtils.makeAccessible(inheritableThreadLocalField); } // ThreadPoolExecutor public AsyncLoadThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } public AsyncLoadThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler); } public AsyncLoadThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); } public AsyncLoadThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); } public <T> AsyncLoadFuture<T> submit(AsyncLoadCallable<T> task) { if (task == null) throw new NullPointerException(); AsyncLoadFuture ftask = new AsyncLoadFuture<T>(task); // Future execute(ftask); return ftask; } // ====================== ========================== @Override public void execute(Runnable command) { if (command instanceof AsyncLoadFuture) { AsyncLoadFuture afuture = (AsyncLoadFuture) command; boolean flag = afuture.getConfig().getNeedThreadLocalSupport(); if (flag) { Thread thread = Thread.currentThread(); if (ReflectionUtils.getField(threadLocalField, thread) == null) { // ThreadLocal, new ThreadLocal<Boolean>(); // runnerThreadLocalMap } if (ReflectionUtils.getField(inheritableThreadLocalField, thread) == null) { // ThreadLocal, new InheritableThreadLocal<Boolean>(); // ?ThreadLocal } } } super.execute(command);// ?? } @Override protected void beforeExecute(Thread t, Runnable command) { // ??ThreadPool if (command instanceof AsyncLoadFuture) { AsyncLoadFuture afuture = (AsyncLoadFuture) command; boolean flag = afuture.getConfig().getNeedThreadLocalSupport(); if (flag) { initThreadLocal(threadLocalField, afuture.getCallerThread(), t); initThreadLocal(inheritableThreadLocalField, afuture.getCallerThread(), t); } } super.beforeExecute(t, command); } @Override protected void afterExecute(Runnable command, Throwable t) { // ???ThreadPoolGC? if (command instanceof AsyncLoadFuture) { AsyncLoadFuture afuture = (AsyncLoadFuture) command; boolean flag = afuture.getConfig().getNeedThreadLocalSupport(); if (flag) { recoverThreadLocal(threadLocalField, afuture.getCallerThread(), afuture.getRunnerThread()); recoverThreadLocal(inheritableThreadLocalField, afuture.getCallerThread(), afuture.getRunnerThread()); } } super.afterExecute(command, t); } private void initThreadLocal(Field field, Thread caller, Thread runner) { if (caller == null || runner == null) { return; } // ? // 1. callerThreadLocalrunnerThreadLocal??caller // 2. ?caller,runnerThreadLocal?,set?ThreadLocal,???? // ??Runnable??ThreadLocalMaprunner???caller?????? // threadlocal?,?? Object callerThreadLocalMap = ReflectionUtils.getField(field, caller); if (callerThreadLocalMap != null) { ReflectionUtils.setField(field, runner, callerThreadLocalMap);// ?caller?runner } else { // ?,execute??? } } private void recoverThreadLocal(Field field, Thread caller, Thread runner) { if (runner == null) { return; } // ?runnerThreadLocaltask? ReflectionUtils.setField(field, runner, null); } }