ConcurrentExecuteService

public abstract class ConcurrentExecuteService<T> {

    private int timeout = 5;
    private TimeUnit timeUnit = TimeUnit.SECONDS;
    private ScheduledExecutorService delayer;
    private ExecutorService executorService;

    public ConcurrentExecuteService(ExecutorService executorService, int delayerSize) {
        this.executorService = executorService;
        delayer = Executors.newScheduledThreadPool(delayerSize);
    }

    public ConcurrentExecuteService(ExecutorService executorService, int delayerSize, ThreadFactory threadFactory) {
        this.executorService = executorService;
        delayer = Executors.newScheduledThreadPool(delayerSize, threadFactory);
    }

    protected abstract T defaultValue();

    public List<T> execute(List<Callable<T>> tasks) {
        return executeSuppliers(tasks.stream().map(mapToSupplier()).collect(Collectors.toList()));
    }

    private Function<Callable<T>, Supplier<T>> mapToSupplier() {
        return callable -> (Supplier<T>) () -> {
            try {
                return callable.call();
            } catch (Exception e) {
                return defaultValue();
            }
        };
    }

    private List<T> executeSuppliers(List<Supplier<T>> suppliers) {
        List<CompletableFuture<T>> supplierFutures = suppliers.stream().map(supplier -> mapToCompletableFuture(supplier)).collect(Collectors.toList());
        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(supplierFutures.toArray(new CompletableFuture[supplierFutures.size()]));
        try {
            return completableFuture.thenApply(future -> supplierFutures.stream().map(supplierFuture -> supplierFuture.join()).collect(Collectors.toList())).get();
        } catch (Exception e) {
            return Lists.newArrayList();
        }
    }

    private CompletableFuture<T> mapToCompletableFuture(Supplier<T> supplier) {
        return CompletableFuture.supplyAsync(supplier, executorService).applyToEither(timeoutAfter(), Function.identity());
    }

    public CompletableFuture<T> timeoutAfter() {
        CompletableFuture<T> result = new CompletableFuture<>();
        delayer.schedule(() -> result.complete(defaultValue()), timeout, timeUnit);
        return result;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public TimeUnit getTimeUnit() {
        return timeUnit;
    }

    public void setTimeUnit(TimeUnit timeUnit) {
        this.timeUnit = timeUnit;
    }
}

 

posted @ 2019-01-22 15:35  TylerJin  阅读(198)  评论(0)    收藏  举报