0

I'm working on Java and I have a "batch" procedure, with multiple objects, and each one of them does something on the db (mainly updates). I want some of them to wait each other, but only if a specific condition is encountered. To be precise, some of them may update the same entity, and Java gives an OptimisticLockException in that case, but some others may update other entities, so they don't have to wait. I would like to create a ReentrantLock (or something that works like that) with a specific ID (in this case, the entity ID), and only the ones which have the same ID may wait until it is unlocked, while the others can execute their code freely.

I don't know if the request is clear, as english is not my first language, sorry. But, I would appreciate if someone can help me!

Thanks in advance.

Cliser
  • 3
  • 1

2 Answers2

0

Cliser you are almost there just one thing you can do is, write repositories of lock that are mapped against ID in your case.

We can use HashMap to main these locks against ID in java.

Steps as below:

  1. in acquire method.. push ID into our hashmap and acquire a lock.
  2. in the release method first you will look if ID exists in hashmap. if it does release the lock if conditions holds true

Let me know if this helps.

cedar
  • 16
  • 2
  • But how can I actually tell the code to wait or not? If I invoke the .lock() method, each element has to wait the previous, no matter what. What i did was to put the ReentrantLock instance into a HashMap with the entity ID as a key, and if there was already an instance, I called the .wait() method, but I don't think it's the right way. – Cliser Jul 26 '23 at 18:58
  • So i would avoid using wait, notify in code as those are really low-level APIs. as you mentioned you are trying out ReentrantLock so only lock and unlock methods will suffice. You are correct on the part where you are putting objects into the map. the only issue is the result you want to achieve. the flow will be if there exists an instance in the map that means the lock is already held by some other thread. In that case, it is already being processed and will be available soon. Hope this helps. – cedar Jul 27 '23 at 04:10
  • But (correct me if I'm wrong) this way, all the threads will have to wait for the previous thread to be unlocked. While, I want some of them to wait and some others not. Maybe I don't need to use a ReentrantLock but something else.. – Cliser Jul 27 '23 at 06:27
0

The idea of the HashMap was correct, but I was calling the .lock() method, while I needed to call the .wait() method only for the threads that needed to wait, while the others could just go on. I created a HashMap<Long, ReentrantLock>, having the entity ID as the key and a new instance of the ReentrantLock as a value. When the "main" thread has finished, it calls the .notify() method, which randomly releases one of the waiting threads (and that's what I want), which (again) releases another thread when finished, and so on.

Cliser
  • 3
  • 1
  • thank you for posting a question and and an answer. for others that come here with the same problem, it would be great to include the code in both the original question and in your solution. – Kirby Jul 31 '23 at 17:01
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 02 '23 at 07:28