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
28 29
 * @see ThreadFactory
 * @see Executors#defaultThreadFactory()
oldratlee's avatar
oldratlee 已提交
30
 * @since 0.9.0
31 32 33 34 35 36 37
 */
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 已提交
38 39
    @Nullable
    public static Executor getTtlExecutor(@Nullable Executor executor) {
oldratlee's avatar
oldratlee 已提交
40
        if (TtlAgent.isTtlAgentLoaded() || null == executor || executor instanceof TtlEnhanced) {
41 42 43 44 45 46 47 48 49 50
            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 已提交
51 52
    @Nullable
    public static ExecutorService getTtlExecutorService(@Nullable ExecutorService executorService) {
oldratlee's avatar
oldratlee 已提交
53
        if (TtlAgent.isTtlAgentLoaded() || executorService == null || executorService instanceof TtlEnhanced) {
54 55 56 57 58 59 60
            return executorService;
        }
        return new ExecutorServiceTtlWrapper(executorService);
    }

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

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

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

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

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

163 164 165
    private TtlExecutors() {
    }
}