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

import com.alibaba.ttl.TransmittableThreadLocal;
4
import com.alibaba.ttl.threadpool.agent.TtlAgent;
5

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

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

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

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

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

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

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

160 161 162
    private TtlExecutors() {
    }
}