我有两个不同的对象但是 它们是等于(obj1!= obj2,但是obj1.equlas(obj2))
如何对这个对象使用同步/锁定? 例如:
...
synchronized(obj) {
doSomething(obj);
}
...
如果其中一个equals()对象已在同一时间执行某些操作,我想锁定它。
答案 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]