com.agapple.asyncload.impl.pool.AsyncLoadThreadPool.java Source code

Java tutorial

Introduction

Here is the source code for com.agapple.asyncload.impl.pool.AsyncLoadThreadPool.java

Source

/*
 * 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);
    }

}