All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.phantomthief.pool.impl.KeyAffinityExecutorBuilder Maven / Gradle / Ivy

The newest version!
package com.github.phantomthief.pool.impl;

import static com.github.phantomthief.pool.impl.KeyAffinityExecutorForStats.wrapStats;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator;
import static com.google.common.util.concurrent.MoreExecutors.shutdownAndAwaitTermination;
import static java.util.Collections.unmodifiableCollection;
import static java.util.concurrent.TimeUnit.DAYS;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.BooleanSupplier;
import java.util.function.IntPredicate;
import java.util.function.IntSupplier;
import java.util.function.Supplier;

import javax.annotation.CheckReturnValue;
import javax.annotation.Nonnull;

import com.github.phantomthief.pool.KeyAffinityExecutor;
import com.github.phantomthief.util.SimpleRateLimiter;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.ListeningExecutorService;

/**
 * {@link KeyAffinityExecutor}构造器
 * 

用于创建{@link KeyAffinityExecutor}的实现类的实例

* * @author w.vela * Created on 2018-02-09. */ @SuppressWarnings("ResultOfMethodCallIgnored") public class KeyAffinityExecutorBuilder { static final Map, KeyAffinityExecutor> ALL_EXECUTORS = new ConcurrentHashMap<>(); private final KeyAffinityBuilder builder = new KeyAffinityBuilder<>(); private boolean usingDynamic = false; private boolean shutdownAfterClose = true; private boolean skipDuplicate = false; /** * 创建{@link KeyAffinityExecutor}对象 * * @return 使用构造器配置创建的{@link KeyAffinityExecutor}对象 */ @Nonnull public KeyAffinityExecutor build() { if (usingDynamic && !shutdownAfterClose) { throw new IllegalStateException("cannot close shutdown after close when enable dynamic count."); } if (shutdownAfterClose) { builder.depose(it -> shutdownAndAwaitTermination(it, 1, DAYS)); } builder.ensure(); KeyAffinityExecutorImpl result = new KeyAffinityExecutorImpl<>(builder::buildInner); result.setSkipDuplicate(skipDuplicate); ALL_EXECUTORS.put(result, wrapStats(result)); return result; } /** * 是否在关闭时自动关闭执行器,默认为true * * @param value 是否在关闭时自动关闭执行器 * @return 当前构造器对象本身 */ @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder shutdownExecutorAfterClose(boolean value) { shutdownAfterClose = value; return this; } /** * 设置任务按Key分发任务到执行器中后,任务执行时,是否跳过的重复任务,仅执行最新的任务 * 跳过时,Callable 类型执行结果为 null, Runnable 默认不执行 * * @param value 是否跳过的重复任务,仅执行最新的任务 * @return 当前构造器对象本身 * see {@link KeyAffinityBuilder#usingRandom(boolean)} */ @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder skipDuplicate(boolean value) { skipDuplicate = value; return this; } /** * 设置任务按Key分发任务到执行器中,是否为随机挑选执行器执行,一般情况下保持默认值即可,无需手工设置 * * @param value 是否使用随机分发,如果为true使用随机方式分发;为false,则挑选当前执行任务数最少的分发 * @return 当前构造器对象本身 * see {@link KeyAffinityBuilder#usingRandom(boolean)} */ @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder usingRandom(boolean value) { builder.usingRandom(value); return this; } /** * 设置任务按Key分发任务到执行器中,是否为随机挑选执行器执行,一般情况下使用 * {@link KeyAffinityExecutor#newSerializingExecutor(int, int, String)}等方法进行构造,无需手工设置 * {@link IntPredicate}的入参为当前使用的执行器的数量 * * @param value 是否使用随机分发,根据当前执行器的数量判断是否使用随机分发,如果结果为true使用随机方式分发; * 为false,则挑选当前执行任务数最少的分发 * @return 当前构造器对象本身 * see {@link KeyAffinityBuilder#usingRandom(boolean)} */ @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder usingRandom(IntPredicate value) { builder.usingRandom(value); return this; } /** * 执行器提供函数,创建一个指定的执行器对象,一般情况下使用 * {@link KeyAffinityExecutor#newSerializingExecutor(int, int, String)}等方法进行构造,无需手工设置 * * @param factory 执行器提供函数 * @return 当前构造器对象本身 */ @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder executor(@Nonnull Supplier factory) { checkNotNull(factory); builder.factory(() -> { ExecutorService executor = factory.get(); if (executor instanceof ListeningExecutorService) { return (ListeningExecutorService) executor; } else if (executor instanceof ThreadPoolExecutor) { return new ThreadListeningExecutorService((ThreadPoolExecutor) executor); } else { return listeningDecorator(executor); } }); return this; } /** * 已废弃:同{@link #parallelism(int)},语义更清晰 * * @param count 设置并发度,即有多少个执行器来处理不同的Key的任务 * @return 当前构造器对象本身 */ @Deprecated @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder count(int count) { return parallelism(count); } /** * 设置并发度,即有多少个执行器来处理不同的Key的任务。由于通常任务执行器的线程数为1,在这种情况下也可以理解成有多少个线程在处理相应的任务 * 要动态设值请使用{@link #parallelism(IntSupplier)} * * @param value 设置并发度,即有多少个执行器来处理不同的Key的任务 * @return 当前构造器对象本身 */ @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder parallelism(int value) { builder.count(value); return this; } /** * 是否启用计数器检查来保证执行器的个数符合预期,默认开启 *

当使用动态配置并发度的情况下(使用{@link #parallelism(IntSupplier)}动态设置)的情况下,此项务必开启

* * @param value 当前是否开启计数器检查 * @return 当前构造器对象本身 */ @CheckReturnValue @Nonnull @VisibleForTesting KeyAffinityExecutorBuilder counterChecker(BooleanSupplier value) { builder.counterChecker(value); return this; } /** * 已废弃:同{@link #parallelism(IntSupplier)},语义更清晰 * * @param count 设置并发度,即有多少个执行器来处理不同的Key的任务 * @return 当前构造器对象本身 */ @Deprecated @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder count(IntSupplier count) { return parallelism(count); } /** * 设置并发度,即有多少个执行器来处理不同的Key的任务。由于通常任务执行器的线程数为1,在这种情况下也可以理解成有多少个线程在处理相应的任务 * {@link #parallelism(int)}的动态设值版本 * * @param count value 设置并发度,即有多少个执行器来处理不同的Key的任务 * @return 当前构造器对象本身 */ @CheckReturnValue @Nonnull public KeyAffinityExecutorBuilder parallelism(IntSupplier count) { builder.count(count); usingDynamic = true; SimpleRateLimiter rateLimiter = SimpleRateLimiter.create(1); builder.counterChecker(rateLimiter::tryAcquire); return this; } /** * 获取当前已经创建的所有{@link KeyAffinityExecutor}对象,通常是统计时使用 * * @return 返回所有已经创建的{@link KeyAffinityExecutor}对象集合 */ public static Collection> getAllExecutors() { return unmodifiableCollection(ALL_EXECUTORS.values()); } @VisibleForTesting static void clearAllExecutors() { ALL_EXECUTORS.clear(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy