package com.alibaba.ttl.threadpool; import com.alibaba.ttl.TransmittableThreadLocal; import com.alibaba.ttl.TtlEnhanced; import com.alibaba.ttl.threadpool.agent.TtlAgent; import javax.annotation.Nullable; import java.util.concurrent.*; /** * Factory Utils for getting TTL wrapper of jdk executors. *

* Note: *

* * @author Jerry Lee (oldratlee at gmail dot com) * @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 * @see ThreadFactory * @see Executors#defaultThreadFactory() * @since 0.9.0 */ 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}. */ @Nullable public static Executor getTtlExecutor(@Nullable Executor executor) { if (TtlAgent.isTtlAgentLoaded() || null == executor || executor instanceof TtlEnhanced) { 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}. */ @Nullable public static ExecutorService getTtlExecutorService(@Nullable ExecutorService executorService) { if (TtlAgent.isTtlAgentLoaded() || executorService == null || executorService instanceof TtlEnhanced) { return executorService; } return new ExecutorServiceTtlWrapper(executorService); } /** * {@link TransmittableThreadLocal} Wrapper of {@link ScheduledExecutorService}, * 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}. */ @Nullable public static ScheduledExecutorService getTtlScheduledExecutorService(@Nullable ScheduledExecutorService scheduledExecutorService) { if (TtlAgent.isTtlAgentLoaded() || scheduledExecutorService == null || scheduledExecutorService instanceof TtlEnhanced) { return scheduledExecutorService; } return new ScheduledExecutorServiceTtlWrapper(scheduledExecutorService); } /** * check the executor is TTL wrapper executor or not. *

* if the parameter executor is TTL wrapper, return {@code true}, otherwise {@code false}. *

* NOTE: if input executor is {@code null}, return {@code false}. * * @param executor input executor * @param Executor type * @see #getTtlExecutor(Executor) * @see #getTtlExecutorService(ExecutorService) * @see #getTtlScheduledExecutorService(ScheduledExecutorService) * @see #unwrap(Executor) * @since 2.8.0 */ public static boolean isTtlWrapper(@Nullable T executor) { return executor instanceof TtlEnhanced; } /** * Unwrap TTL wrapper executor to the original/underneath one. *

* if the parameter executor is TTL wrapper, return the original/underneath executor; * otherwise, just return the input parameter executor. *

* NOTE: if input executor is {@code null}, return {@code null}. * * @param executor input executor * @param Executor type * @see #getTtlExecutor(Executor) * @see #getTtlExecutorService(ExecutorService) * @see #getTtlScheduledExecutorService(ScheduledExecutorService) * @see #isTtlWrapper(Executor) * @since 2.8.0 */ @Nullable @SuppressWarnings("unchecked") public static T unwrap(@Nullable T executor) { if (!isTtlWrapper(executor)) return executor; return (T) ((ExecutorTtlWrapper) executor).unwrap(); } /** * 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(); } private TtlExecutors() { } }