【问题标题】:Using different objects for one synchronization/lock in Java在 Java 中为一个同步/锁定使用不同的对象
【发布时间】:2016-05-29 07:52:22
【问题描述】:

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

我怎样才能对这个对象使用同步/锁定? 例如:

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

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

【问题讨论】:

  • 锁在 java 中不使用 equals。锁在 Object 实例本身上。
  • 我知道,我的问题是如何使用 equals() 实现它
  • 如果它们不相等会怎样?完全没有同步?两者的同步?..
  • 如果他们不相等,他们应该为每个同步
  • 检查这些问题:123。大多数答案适用于任何对象。我会选择 Guava 的 Striped 类,准确地说是它的 lazyWeakLock 方法。

标签: java concurrency synchronization locking


【解决方案1】:

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

解决办法是:

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

但如果你在另一个线程中颠倒顺序,你会得到一个死锁。

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

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

【讨论】:

    【解决方案2】:

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

    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]
    

    【讨论】:

    • 谢谢,对我有帮助!
    • @AskProgram 请不要忘记标记实际有效的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 2014-03-11
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多