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

tech.ytsaurus.client.misc.SerializedExecutorService Maven / Gradle / Ivy

The newest version!
package tech.ytsaurus.client.misc;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.annotation.Nonnull;

/**
 * An executor than ensurers serial execution of submitted tasks
 * i.e. no two tasks submitted to it will be executed simultaneously.
 */
public class SerializedExecutorService implements ExecutorService {
    private final ExecutorService underlying;
    private final AtomicBoolean lock = new AtomicBoolean();
    private final ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>();

    public SerializedExecutorService(@Nonnull ExecutorService underlying) {
        this.underlying = underlying;
    }

    @Override
    public void shutdown() {
        underlying.shutdown();
    }

    @Nonnull
    @Override
    public List shutdownNow() {
        List result = underlying.shutdownNow();
        result.addAll(taskQueue);
        return result;
    }

    @Override
    public boolean isShutdown() {
        return underlying.isShutdown();
    }

    @Override
    public boolean isTerminated() {
        return underlying.isTerminated();
    }

    @Override
    public boolean awaitTermination(long l, @Nonnull TimeUnit timeUnit) throws InterruptedException {
        return underlying.awaitTermination(l, timeUnit);
    }

    @Nonnull
    @Override
    public  CompletableFuture submit(@Nonnull Callable callable) {
        CompletableFuture result = new CompletableFuture<>();
        execute(() -> {
            if (!result.isDone()) {
                try {
                    result.complete(callable.call());
                } catch (Throwable exception) {
                    result.completeExceptionally(exception);
                }
            }
        });
        return result;
    }

    @Nonnull
    @Override
    public  CompletableFuture submit(@Nonnull Runnable runnable, T t) {
        return submit(() -> {
            runnable.run();
            return t;
        });
    }

    @Nonnull
    @Override
    public CompletableFuture submit(@Nonnull Runnable runnable) {
        return submit(() -> {
            runnable.run();
            return null;
        });
    }

    @Nonnull
    @Override
    public  List> invokeAll(@Nonnull Collection> collection) {
        throw new RuntimeException("Not implemented yet");
    }

    @Nonnull
    @Override
    public  List> invokeAll(
            @Nonnull Collection> collection,
            long l,
            @Nonnull TimeUnit timeUnit
    ) {
        throw new RuntimeException("Not implemented yet");
    }

    @Nonnull
    @Override
    public  T invokeAny(@Nonnull Collection> collection) {
        throw new RuntimeException("Not implemented yet");
    }

    @Override
    public  T invokeAny(@Nonnull Collection> collection, long l, @Nonnull TimeUnit timeUnit) {
        throw new RuntimeException("Not implemented yet");
    }

    @Override
    public void execute(@Nonnull Runnable runnable) {
        taskQueue.add(runnable);
        trySchedule();
    }

    private void trySchedule() {
        if (lock.compareAndSet(false, true)) {
            underlying.execute(() -> {
                Runnable r = taskQueue.poll();
                if (r != null) {
                    r.run();
                }
                lock.set(false);
                if (!taskQueue.isEmpty()) {
                    trySchedule();
                }
            });
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy