0

I have two different objects but they are equals (obj1 != obj2, but obj1.equlas(obj2))

How can I use synchronization/lock for this objects like one? For example:

...
synchronized(obj) {
        doSomething(obj);
}
...

I want to lock it if one of the equals() object already doing something in the same time.

  • Locks do not use equals in java.Lock is on Object instance itself. – Ankit Tripathi May 29 '16 at 08:06
  • I know it and my question is how it can be implemented using equals() – AskProgram May 29 '16 at 08:27
  • What should happen if they aren't equal? No synchronization at all? Synchronization of either?.. – Andrey Lebedenko May 29 '16 at 10:47
  • If they aren't equal they should synchronization for each – AskProgram May 29 '16 at 16:40
  • Check these questions: [1](http://stackoverflow.com/questions/11124539/how-to-acquire-a-lock-by-a-key), [2](http://stackoverflow.com/questions/12450402/java-synchronizing-based-on-a-parameter/28347825#28347825), [3](http://stackoverflow.com/questions/5639870/simple-java-name-based-locks). Most answers work for any objects. I would go with the Guava's [Striped](http://google.github.io/guava/releases/19.0/api/docs/com/google/common/util/concurrent/Striped.html) class, its `lazyWeakLock` method to be precise. – starikoff May 30 '16 at 10:34

2 Answers2

0

There is no way to use just one synchronized (object) and get both objects synchronized.

The solutions is:

synchronized (obj) {
      synchronized (obj2) { ......

but if you invert the order in onother thread you can get a dead lock.

or the other solution, one I suggest, is to make your obj static and use to synchronize.

what you have is meaningfully equals objects, but the reference of variable that you have for obj and obj2 are pointing for different objects.

G Bisconcini
  • 764
  • 2
  • 6
  • 25
0

I can't say I fully understand why this could be required, but using wrapper approach may potentially help:

public class SyncOnEquals {
    public synchronized Object getSync(Object o1, Object o2)
    {
        if(o1.equals(o2))
            return this;
        else
            return o1;
    }
}

Test:

@org.junit.Test
public void testSyncOnEqual() {
System.out.println("syncOnEqual");
Integer o1 = new Integer(125);
Integer o2 = new Integer(125);

System.out.println("o1 == o2: "+(o1==o2));
System.out.println("o1.equals(o2): "+o1.equals(o2));
SyncOnEquals sync = new SyncOnEquals();

Thread t1 = new Thread(){
    public void run()
    {
        System.out.println("Waiting thread "+Thread.currentThread());
        synchronized(sync.getSync(o1, o2))
        {
            System.out.println("Working thread "+Thread.currentThread());
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        System.out.println("Finished thread "+Thread.currentThread());
    }
};

Thread t2 = new Thread(){
    public void run()
    {
        System.out.println("Waiting thread "+Thread.currentThread());
        synchronized(sync.getSync(o2, o1))
        {
            System.out.println("Working thread "+Thread.currentThread());
            try {
                Thread.currentThread().sleep(500);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        System.out.println("Finished thread "+Thread.currentThread());
    }
};

t1.start();
t2.start();

try{
    Thread.currentThread().sleep(2000);
} catch (InterruptedException ex) {
    ex.printStackTrace();

    }
}

Output:

syncOnEqual
o1 == o2: false
o1.equals(o2): true
Waiting thread Thread[Thread-0,5,main]
Waiting thread Thread[Thread-1,5,main]
Working thread Thread[Thread-0,5,main]
Finished thread Thread[Thread-0,5,main]
Working thread Thread[Thread-1,5,main]
Finished thread Thread[Thread-1,5,main]
Andrey Lebedenko
  • 1,850
  • 17
  • 24