Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to acquire multiple locks without ordering constraints in Java?

So I have code similar to this

synchronized(objectOne){ do stuff }
synchronized(objectTwo){ do stuff }

The problem with this is the program will wait for the lock on objectOne, even if the lock for objectTwo is available. What I'm trying to do is say: try to lock both objectOne and objectTwo, and whichever lock you get first do the stuff for that lock. I've come up with a solution but I think it's rather hacky and I'm wondering if anybody has any better ideas.

Here's my idea: Start 2 threads, each one waiting on a lock and then the main thread will wait on a CountDownLatch. So you end up with something like this:

CountDownLatch latch = new CountDownLatch(2);

new Thread(new Runnable(){
public void run(){
    synchronized(objectOne) { do stuff }
    latch.countDown();
}).start();

new Thread(new Runnable(){
public void run(){
    synchronized(objectTwo) { do stuff }
    latch.countDown();
}).start();

latch.await();
like image 787
user1825426 Avatar asked Nov 15 '12 01:11

user1825426


2 Answers

I think you should use Lock which provides you with the method boolean tryLock().

Returns: true if the lock was acquired and false otherwise

Proceed with do stuff when you have at least one of the locks.

like image 146
Bhesh Gurung Avatar answered Sep 23 '22 04:09

Bhesh Gurung


You might want to have 2 queues of jobs, 2 threads each polling a queue and execute the jobs.

For jobs related to objectOne, you put it in queue#1; jobs related to objectTwo in queue#2.

worker1.queue.put( new Runnable(){ public void run() { do stuff } } );
worker2.queue.put( new Runnable(){ public void run() { do stuff } } );

----

class Worker extends Thread

    BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();

    public void run()
        while(true)
            queue.take().run();
like image 34
irreputable Avatar answered Sep 24 '22 04:09

irreputable