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

shz.core.lock.ActionAndWait Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core.lock;

import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;

public final class ActionAndWait {
    private final Lock lock;
    private final long sleepMillis;
    private final Condition waiter;
    private final AtomicInteger state;
    private volatile boolean running;

    public ActionAndWait(Lock lock, long sleepMillis) {
        this.lock = lock;
        this.sleepMillis = sleepMillis;
        waiter = lock.newCondition();
        state = new AtomicInteger();
    }

    public ActionAndWait() {
        this(new ReentrantLock(), 0L);
    }

    public void execute(Supplier action) {
        try {
            lock.lockInterruptibly();
            long waitTime = 0L;
            do {
                state.set(0);
                running = true;
                try {
                    Duration duration = action.get();
                    waitTime = duration == null ? 0L : duration.toNanos();
                } catch (Exception ignored) {
                }
            } while (!state.compareAndSet(0, 1));
            try {
                if (waitTime <= 0L) waiter.await();
                else waiter.await(waitTime, TimeUnit.NANOSECONDS);
            } catch (InterruptedException ignored) {
            }
            state.set(2);
            running = false;
            if (sleepMillis > 0L) TimeUnit.MILLISECONDS.sleep(sleepMillis);
        } catch (InterruptedException ignored) {
        } finally {
            lock.unlock();
        }
    }

    public void awaken() {
        do {
            if (state.get() == 2) break;
            if (lock.tryLock()) {
                try {
                    waiter.signal();
                } finally {
                    lock.unlock();
                }
                break;
            }
        } while (state.get() == 1 || !state.compareAndSet(0, 2));
    }

    public boolean isRunning() {
        return running;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy