I've a situation where I need to implement a thread safe method, The method must be executed by only one thread at a time, And while the method is being executed by a thread, all other threads trying to execute the same method shouldn't wait and must exit the method.
Synchronization won't help here since threads will be waiting to execute the method sequentially.
I thought I would achieve this by making use of ConcurrentHashMap using below code, but not sure if this is the perfect way to implement it.
Class Test {
private ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();
public void execute() {
if (map.putIfApsent("key", new Object()) != null) { // map has value for key which means a thread has already entered.
return; // early exit
}
threadSafeMethod();
map.remove("key");
}
private void threadSafeMethod() {
// my code
}
}
CodePudding user response:
You can do this without synchronization, with compare-and-swap using a boolean:
private AtomicBoolean entered = new AtomicBoolean(false);
public void execute() {
if(entered.compareAndSet(false,true) {
try {
method()
} finally {
entered.set(false)
}
}
}
CodePudding user response:
You could use a ReentrantLock
and specify a negative value for waiting time. In that case the scheduler will not try to wait if there is a thread already executing the code.
// define the lock somewhere as an instance variable
Lock lock = new ReentrantLock();
try {
var isAvailable = lock.tryLock(-1, TimeUnit.NANOSECONDS);
if(isAvailable) {
System.out.println("do work");
lock.unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
}