TtlExecutors.java 6.2 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.TtlEnhanced;
5
import com.alibaba.ttl.threadpool.agent.TtlAgent;
6

oldratlee's avatar
oldratlee 已提交
7
import javax.annotation.Nullable;
8
import java.util.concurrent.*;
9 10

/**
11
 * Factory Utils for getting TTL wrapper of jdk executors.
12 13 14 15 16 17 18
 * <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>
 * <li>skip decorating thread pool/{@code executor}(aka. just return input {@code executor})
 * when ttl agent is loaded, Or when input {@code executor} is already decorated.</li>
 * </ul>
19 20
 *
 * @author Jerry Lee (oldratlee at gmail dot com)
oldratlee's avatar
oldratlee 已提交
21 22 23 24 25 26 27
 * @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
oldratlee's avatar
oldratlee 已提交
28
 * @since 0.9.0
29 30 31 32 33 34 35
 */
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 已提交
36 37
    @Nullable
    public static Executor getTtlExecutor(@Nullable Executor executor) {
oldratlee's avatar
oldratlee 已提交
38
        if (TtlAgent.isTtlAgentLoaded() || null == executor || executor instanceof TtlEnhanced) {
39 40 41 42 43 44 45 46 47 48
            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 已提交
49 50
    @Nullable
    public static ExecutorService getTtlExecutorService(@Nullable ExecutorService executorService) {
oldratlee's avatar
oldratlee 已提交
51
        if (TtlAgent.isTtlAgentLoaded() || executorService == null || executorService instanceof TtlEnhanced) {
52 53 54 55 56 57 58
            return executorService;
        }
        return new ExecutorServiceTtlWrapper(executorService);
    }

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

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
    /**
     * 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 已提交
85
    public static <T extends Executor> boolean isTtlWrapper(@Nullable T executor) {
oldratlee's avatar
oldratlee 已提交
86
        return executor instanceof TtlEnhanced;
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
    }

    /**
     * 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)
     * @since 2.8.0
     */
oldratlee's avatar
oldratlee 已提交
105
    @Nullable
106
    @SuppressWarnings("unchecked")
oldratlee's avatar
oldratlee 已提交
107
    public static <T extends Executor> T unwrap(@Nullable T executor) {
108 109 110 111 112
        if (!isTtlWrapper(executor)) return executor;

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

113 114 115 116 117 118 119 120 121 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 148 149 150 151 152 153 154 155 156 157 158 159 160
    /**
     * 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());
    }

    /**
     * check the {@link ThreadFactory} is  {@link DisableInheritableThreadFactory} or not.
     *
     * @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.
     *
     * @see DisableInheritableThreadFactory
     * @since 2.10.0
     */
    @Nullable
    public static ThreadFactory unwrap(@Nullable ThreadFactory threadFactory) {
        if (!isDisableInheritableThreadFactory(threadFactory)) return threadFactory;

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

161 162 163
    private TtlExecutors() {
    }
}