I have a process A that contains a table in memory with a set of records (recordA, recordB, etc...)
Now, this process can launch many threads that affect the records, and sometimes we can have 2 threads trying to access the same record - this situation must be denied. Specifically if a record is LOCKED by one thread I want the other thread to abort (I do not want to BLOCK or WAIT).
Currently I do something like this:
synchronized(record) { performOperation(record); }
But this is causing me problems ... because while Process1 is performing the operation, if Process2 comes in it blocks/waits on the synchronized statement and when Process1 is finished it performs the operation. Instead I want something like this:
if (record is locked) return; synchronized(record) { performOperation(record); }
Any clues on how this can be accomplished? Any help would be much appreciated. Thanks,
When a method is declared as synchronized; the thread holds the monitor or lock object for that method's object. If another thread is executing the synchronized method, your thread is blocked until that thread releases the monitor.
A Java synchronized block marks a method or a block of code as synchronized. A synchronized block in Java can only be executed a single thread at a time (depending on how you use it). Java synchronized blocks can thus be used to avoid race conditions.
Major difference between lock and synchronized: with locks, you can release and acquire the locks in any order. with synchronized, you can release the locks only in the order it was acquired.
You can check the lock on the particular object by calling wait() or notify() method on that object. If the object does not hold the lock, then it will throw llegalMonitorStateException . 2- By calling holdsLock(Object o) method. This will return the boolean value.
One thing to note is that the instant you receive such information, it's stale. In other words, you could be told that no-one has the lock, but then when you try to acquire it, you block because another thread took out the lock between the check and you trying to acquire it.
Brian is right to point at Lock
, but I think what you really want is its tryLock
method:
Lock lock = new ReentrantLock(); ...... if (lock.tryLock()) { // Got the lock try { // Process record } finally { // Make sure to unlock so that we don't cause a deadlock lock.unlock(); } } else { // Someone else had the lock, abort }
You can also call tryLock
with an amount of time to wait - so you could try to acquire it for a tenth of a second, then abort if you can't get it (for example).
(I think it's a pity that the Java API doesn't - as far as I'm aware - provide the same functionality for the "built-in" locking, as the Monitor
class does in .NET. Then again, there are plenty of other things I dislike in both platforms when it comes to threading - every object potentially having a monitor, for example!)
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