在Java中使用不同的对象进行一次同步/锁定

时间:2016-05-29 07:52:23

标签: java concurrency synchronization locking

我有两个不同的对象但是 它们是等于(obj1!= obj2,但是obj1.equlas(obj2))

如何对这个对象使用同步/锁定? 例如:

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

如果其中一个equals()对象已在同一时间执行某些操作,我想锁定它。

2 个答案:

答案 0 :(得分:0)

无法仅使用一个synchronized(对象)并使两个对象同步。

解决方案是:

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

但是如果你在另一个线程中反转顺序,你就可以获得死锁。

或其他解决方案,我建议,是让你的obj静态并用于同步。

你所拥有的是有意义的等于对象,但你对obj和obj2的变量的引用指向不同的对象。

答案 1 :(得分:0)

我不能说我完全理解为什么需要这样做,但使用包装器方法可能可能有所帮助:

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

测试:

@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();

    }
}

输出:

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]