Simplify acquisition

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-09-09 20:49:54 +02:00
parent acb8634b4b
commit f48199397a
3 changed files with 26 additions and 38 deletions

View File

@ -84,8 +84,7 @@ public interface Acquirable<T> {
* @see #sync(Consumer) for auto-closeable capability * @see #sync(Consumer) for auto-closeable capability
*/ */
default @NotNull Acquired<T> lock() { default @NotNull Acquired<T> lock() {
final Optional<T> optional = local(); return new Acquired<>(unwrap(), getHandler().getTickThread());
return optional.map(Acquired::local).orElseGet(() -> Acquired.locked(this));
} }
/** /**

View File

@ -37,32 +37,37 @@ final class AcquirableImpl<T> implements Acquirable<T> {
return handler; return handler;
} }
static @Nullable ReentrantLock enter(@Nullable Thread currentThread, @Nullable TickThread elementThread) { static @Nullable ReentrantLock enter(@NotNull Thread currentThread, @Nullable TickThread elementThread) {
if (elementThread == null) return null;
if (currentThread == elementThread) return null;
final ReentrantLock currentLock = currentThread instanceof TickThread ? ((TickThread) currentThread).getLock() : null;
final ReentrantLock targetLock = elementThread.getLock();
if (targetLock.isHeldByCurrentThread()) return null;
// Monitoring // Monitoring
final long time = System.nanoTime(); final long time = System.nanoTime();
ReentrantLock currentLock; // Enter the target thread
{ // TODO reduce global lock scope
final ReentrantLock lock = currentThread instanceof TickThread ? if (currentLock != null) {
((TickThread) currentThread).getLock() : null; while (!GLOBAL_LOCK.tryLock()) {
currentLock = lock != null && lock.isHeldByCurrentThread() ? lock : null; currentLock.unlock();
currentLock.lock();
} }
if (currentLock != null) currentLock.unlock(); } else {
GLOBAL_LOCK.lock(); GLOBAL_LOCK.lock();
if (currentLock != null) currentLock.lock(); }
targetLock.lock();
final ReentrantLock lock = elementThread != null ? elementThread.getLock() : null;
final boolean acquired = lock == null || lock.isHeldByCurrentThread();
if (!acquired) lock.lock();
// Monitoring // Monitoring
AcquirableImpl.WAIT_COUNTER_NANO.addAndGet(System.nanoTime() - time); WAIT_COUNTER_NANO.addAndGet(System.nanoTime() - time);
return targetLock;
return !acquired ? lock : null;
} }
static void leave(@Nullable ReentrantLock lock) { static void leave(@Nullable ReentrantLock lock) {
if (lock != null) lock.unlock(); if (lock != null) {
lock.unlock();
GLOBAL_LOCK.unlock(); GLOBAL_LOCK.unlock();
} }
}
} }

View File

@ -8,27 +8,12 @@ import java.util.concurrent.locks.ReentrantLock;
public final class Acquired<T> { public final class Acquired<T> {
private final T value; private final T value;
private final boolean locked;
private final ReentrantLock lock; private final ReentrantLock lock;
private boolean unlocked; private boolean unlocked;
static <T> Acquired<T> local(@NotNull T value) { Acquired(T value, TickThread tickThread) {
return new Acquired<>(value, false, null, null);
}
static <T> Acquired<T> locked(@NotNull Acquirable<T> acquirable) {
final Thread currentThread = Thread.currentThread();
final TickThread tickThread = acquirable.getHandler().getTickThread();
return new Acquired<>(acquirable.unwrap(), true, currentThread, tickThread);
}
private Acquired(@NotNull T value,
boolean locked, Thread currentThread, TickThread tickThread) {
this.value = value; this.value = value;
this.locked = locked; this.lock = AcquirableImpl.enter(Thread.currentThread(), tickThread);
this.lock = locked ? AcquirableImpl.enter(currentThread, tickThread) : null;
} }
public @NotNull T get() { public @NotNull T get() {
@ -39,7 +24,6 @@ public final class Acquired<T> {
public void unlock() { public void unlock() {
checkLock(); checkLock();
this.unlocked = true; this.unlocked = true;
if (!locked) return;
AcquirableImpl.leave(lock); AcquirableImpl.leave(lock);
} }