繁体   English   中英

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

[英]Using different objects for one synchronization/lock in Java

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

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

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

如果equals()对象之一已经在同一时间做某事,我想锁定它。

没有办法只使用一个同步的(对象)并使两个对象同步。

解决方案是:

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

但是,如果您在另一个线程上反转顺序,则会死锁。

我建议的另一种解决方案是使obj静态并用于同步。

您所拥有的实际上是等于对象,但是您对obj和obj2拥有的变量引用指向的是不同的对象。

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

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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM