TtlExecutors.java 6.6 KB
Newer Older
1 2 3
package com.alibaba.ttl.threadpool;

import com.alibaba.ttl.TransmittableThreadLocal;
oldratlee's avatar
oldratlee 已提交
4
import com.alibaba.ttl.spi.TtlEnhanced;
5
import com.alibaba.ttl.threadpool.agent.TtlAgent;
6
import edu.umd.cs.findbugs.annotations.Nullable;
7

8
import java.util.concurrent.*;
9 10

/**
oldratlee's avatar
oldratlee 已提交
11 12 13 14 15 16 17
 * Util methods for TTL wrapper of jdk executors.
 *
 * <ol>
 *     <li>Factory methods to get TTL wrapper from jdk executors.</li>
 *     <li>unwrap/check methods for TTL wrapper of jdk executors.</li>
 *     <li>wrap/unwrap/check methods to disable Inheritable for {@link ThreadFactory}.</li>
 * </ol>
18 19 20 21
 * <p>
 * <b><i>Note:</i></b>
 * <ul>
 * <li>all method is {@code null}-safe, when input {@code executor} parameter is {@code null}, return {@code null}.</li>
oldratlee's avatar
oldratlee 已提交
22 23
 * <li>skip wrap/decoration thread pool/{@code executor}(aka. just return input {@code executor})
 * when ttl agent is loaded, Or when input {@code executor} is already wrapped/decorated.</li>
24
 * </ul>
25 26
 *
 * @author Jerry Lee (oldratlee at gmail dot com)
oldratlee's avatar
oldratlee 已提交
27 28 29 30 31 32 33
 * @see java.util.concurrent.Executor
 * @see java.util.concurrent.ExecutorService
 * @see java.util.concurrent.ThreadPoolExecutor
 * @see java.util.concurrent.ScheduledThreadPoolExecutor
 * @see java.util.concurrent.Executors
 * @see java.util.concurrent.CompletionService
 * @see java.util.concurrent.ExecutorCompletionService
34 35
 * @see ThreadFactory
 * @see Executors#defaultThreadFactory()
oldratlee's avatar
oldratlee 已提交
36
 * @since 0.9.0
37 38 39 40 41 42 43
 */
public final class TtlExecutors {
    /**
     * {@link TransmittableThreadLocal} Wrapper of {@link Executor},
     * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable}
     * to the execution time of {@link Runnable}.
     */
oldratlee's avatar
oldratlee 已提交
44 45
    @Nullable
    public static Executor getTtlExecutor(@Nullable Executor executor) {
oldratlee's avatar
oldratlee 已提交
46
        if (TtlAgent.isTtlAgentLoaded() || null == executor || executor instanceof TtlEnhanced) {
47 48 49 50 51 52 53 54 55 56
            return executor;
        }
        return new ExecutorTtlWrapper(executor);
    }

    /**
     * {@link TransmittableThreadLocal} Wrapper of {@link ExecutorService},
     * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link java.util.concurrent.Callable}
     * to the execution time of {@link Runnable} or {@link java.util.concurrent.Callable}.
     */
oldratlee's avatar
oldratlee 已提交
57 58
    @Nullable
    public static ExecutorService getTtlExecutorService(@Nullable ExecutorService executorService) {
oldratlee's avatar
oldratlee 已提交
59
        if (TtlAgent.isTtlAgentLoaded() || executorService == null || executorService instanceof TtlEnhanced) {
60 61 62 63 64 65 66
            return executorService;
        }
        return new ExecutorServiceTtlWrapper(executorService);
    }

    /**
     * {@link TransmittableThreadLocal} Wrapper of {@link ScheduledExecutorService},
oldratlee's avatar
oldratlee 已提交
67
     * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link java.util.concurrent.Callable}
68 69
     * to the execution time of {@link Runnable} or {@link java.util.concurrent.Callable}.
     */
oldratlee's avatar
oldratlee 已提交
70 71
    @Nullable
    public static ScheduledExecutorService getTtlScheduledExecutorService(@Nullable ScheduledExecutorService scheduledExecutorService) {
oldratlee's avatar
oldratlee 已提交
72
        if (TtlAgent.isTtlAgentLoaded() || scheduledExecutorService == null || scheduledExecutorService instanceof TtlEnhanced) {
73 74 75 76 77
            return scheduledExecutorService;
        }
        return new ScheduledExecutorServiceTtlWrapper(scheduledExecutorService);
    }

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    /**
     * check the executor is TTL wrapper executor or not.
     * <p>
     * if the parameter executor is TTL wrapper, return {@code true}, otherwise {@code false}.
     * <p>
     * NOTE: if input executor is {@code null}, return {@code false}.
     *
     * @param executor input executor
     * @param <T>      Executor type
     * @see #getTtlExecutor(Executor)
     * @see #getTtlExecutorService(ExecutorService)
     * @see #getTtlScheduledExecutorService(ScheduledExecutorService)
     * @see #unwrap(Executor)
     * @since 2.8.0
     */
oldratlee's avatar
oldratlee 已提交
93
    public static <T extends Executor> boolean isTtlWrapper(@Nullable T executor) {
oldratlee's avatar
oldratlee 已提交
94
        return executor instanceof TtlEnhanced;
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
    }

    /**
     * Unwrap TTL wrapper executor to the original/underneath one.
     * <p>
     * if the parameter executor is TTL wrapper, return the original/underneath executor;
     * otherwise, just return the input parameter executor.
     * <p>
     * NOTE: if input executor is {@code null}, return {@code null}.
     *
     * @param executor input executor
     * @param <T>      Executor type
     * @see #getTtlExecutor(Executor)
     * @see #getTtlExecutorService(ExecutorService)
     * @see #getTtlScheduledExecutorService(ScheduledExecutorService)
     * @see #isTtlWrapper(Executor)
oldratlee's avatar
oldratlee 已提交
111
     * @see com.alibaba.ttl.TtlUnwrap#unwrap(Object)
112 113
     * @since 2.8.0
     */
oldratlee's avatar
oldratlee 已提交
114
    @Nullable
115
    @SuppressWarnings("unchecked")
oldratlee's avatar
oldratlee 已提交
116
    public static <T extends Executor> T unwrap(@Nullable T executor) {
117 118 119 120 121
        if (!isTtlWrapper(executor)) return executor;

        return (T) ((ExecutorTtlWrapper) executor).unwrap();
    }

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    /**
     * Wrapper of  {@link ThreadFactory}, disable inheritable.
     *
     * @param threadFactory input thread factory
     * @see DisableInheritableThreadFactory
     * @since 2.10.0
     */
    @Nullable
    public static ThreadFactory getDisableInheritableThreadFactory(@Nullable ThreadFactory threadFactory) {
        if (threadFactory == null || isDisableInheritableThreadFactory(threadFactory)) return threadFactory;

        return new DisableInheritableThreadFactoryWrapper(threadFactory);
    }

    /**
     * Wrapper of {@link Executors#defaultThreadFactory()}, disable inheritable.
     *
     * @see #getDisableInheritableThreadFactory(ThreadFactory)
     * @since 2.10.0
     */
    @Nullable
    public static ThreadFactory getDefaultDisableInheritableThreadFactory() {
        return getDisableInheritableThreadFactory(Executors.defaultThreadFactory());
    }

    /**
148
     * check the {@link ThreadFactory} is {@link DisableInheritableThreadFactory} or not.
149 150 151 152 153 154 155 156 157 158 159
     *
     * @see DisableInheritableThreadFactory
     * @since 2.10.0
     */
    public static boolean isDisableInheritableThreadFactory(@Nullable ThreadFactory threadFactory) {
        return threadFactory instanceof DisableInheritableThreadFactory;
    }

    /**
     * Unwrap {@link DisableInheritableThreadFactory} to the original/underneath one.
     *
oldratlee's avatar
oldratlee 已提交
160
     * @see com.alibaba.ttl.TtlUnwrap#unwrap(Object)
161 162 163 164 165 166 167 168 169 170
     * @see DisableInheritableThreadFactory
     * @since 2.10.0
     */
    @Nullable
    public static ThreadFactory unwrap(@Nullable ThreadFactory threadFactory) {
        if (!isDisableInheritableThreadFactory(threadFactory)) return threadFactory;

        return ((DisableInheritableThreadFactory) threadFactory).unwrap();
    }

171 172 173
    private TtlExecutors() {
    }
}