I have a critical section, I need to control that only those threads with a given attribute value are able to enter at the same time.
For example: I have Thread#1 that handles products, Thread#2 handles products too and Thread#3 handles services
now:
T1 comes first and enters the critical section, so that the product is handled
T2 wants to enter, but since there is another product being processed, it must wait
T3 comes last, it is able to enter, since it needs a service (not a product) to be processed
T1 goes out, now T2 is able to get in
I think it looks quite simple, but I wasn't able to find anything that fits the requirement. My question is, how can I achieve this? any reference to any source of information about this will be appreciated
Thank you very much in advance
How about this:
private ConcurrentMap<Integer, Semaphore> semaphores = new ConcurrentHashMap<>();
public void enter(int id) {
Semaphore s = semaphores.computeIfAbsent(id, key -> new Semaphore(1));
try {
s.acquire();
// Critical section.
} catch (InterruptedException e) {
// Exception handling.
} finally {
s.release();
}
}
tryEnter(int)
via Semaphore#tryAcquire()
.I think you cannot lock on value types but try this workaround: Put lock objects in an array and access the array from ID.
Something like:
private Object[] locks = new Object[] {new Object(), new Object()};
private void yourMethod(int id)
{
synchronized(locks[id]) //or id - 1 if you want to stick to your 1 and 2
{
//do your things
}
}
Hope it helps
If you really need this logic, it can be implemented this way:
private final Lock lock = new Lock();
public void process() {
boolean locked = false;
if (isProduct()) { // Depends on the current thread
lock.lock();
locked = true;
}
try {
// Do the work here
} finally {
if (locked) {
lock.unlock();
}
}
}
But the question itself tells about a poor design. Just create methods processProduct()
and processService()
, make the first one synchronized
and call the one you really need from your threads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With