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

com.firefly.utils.concurrent.Locker Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
package com.firefly.utils.concurrent;

import com.firefly.utils.function.Action0;
import com.firefly.utils.function.Func0;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 

* This is a lock designed to protect VERY short sections of critical code. * Threads attempting to take the lock will wait until the lock is available, * thus it is important that the code protected by this lock is extremely simple * and non blocking. *

* *
 * try (SpinLock.Lock lock = locker.lock()) {
 * 	// something very quick and non blocking
 * }
 * 
*/ public class Locker { private static final boolean SPIN = Boolean.getBoolean(Locker.class.getName() + ".spin"); private final boolean _spin; private final ReentrantLock _lock = new ReentrantLock(); private final AtomicReference _spinLockState = new AtomicReference<>(null); private final Lock _unlock = new Lock(); public Locker() { this(SPIN); } public Locker(boolean spin) { this._spin = spin; } public Lock lock() { if (_spin) spinLock(); else concLock(); return _unlock; } private void spinLock() { Thread current = Thread.currentThread(); while (true) { // Using test-and-test-and-set for better performance. Thread locker = _spinLockState.get(); if (locker != null || !_spinLockState.compareAndSet(null, current)) { if (locker == current) throw new IllegalStateException("Locker is not reentrant"); continue; } return; } } private void concLock() { if (_lock.isHeldByCurrentThread()) throw new IllegalStateException("Locker is not reentrant"); _lock.lock(); } public boolean isLocked() { if (_spin) return _spinLockState.get() != null; else return _lock.isLocked(); } public class Lock implements AutoCloseable { @Override public void close() { if (_spin) _spinLockState.set(null); else _lock.unlock(); } } public void lock(Action0 action0) { try (Lock lock = lock()) { action0.call(); } } public T lock(Func0 func0) { try (Lock lock = lock()) { return func0.call(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy