Java 同步重叠的方法集

Java 同步重叠的方法集,java,thread-synchronization,Java,Thread Synchronization,假设一个Java类有三种方法: public class Lock { private final Object master_foo = null; private final Object master_bar = null; public void master() { synchronized(master_foo) { synchronized(master_bar) { ...

假设一个Java类有三种方法:

public class Lock {
    private final Object master_foo = null;
    private final Object master_bar = null;
    public void master() {
        synchronized(master_foo) {
            synchronized(master_bar) {
                ...
            }
        }
    }

    public void foo() {
        synchronized(master_foo) {
            ...
        }
    }

    public void bar() {
        synchronized(master_bar) {
            ...
        }
    }
}
  • master()
  • foo()
  • bar()

  • 我想同步
    master()
    foo()
    以及
    master()
    bar()
    ,而不同步
    foo()
    bar()
    。可以为每一对同步方法使用单独的锁,但我的实际代码有三种以上的方法,因此我希望有一种方法可以在没有这么多锁对象的情况下实现。

    您可以在任何
    对象上使用
    synchronized
    。因此,您可以为以下方法创建单独的锁:

    public class Lock {
        private final Object master_foo = null;
        private final Object master_bar = null;
        public void master() {
            synchronized(master_foo) {
                synchronized(master_bar) {
                    ...
                }
            }
        }
    
        public void foo() {
            synchronized(master_foo) {
                ...
            }
        }
    
        public void bar() {
            synchronized(master_bar) {
                ...
            }
        }
    }
    

    你本质上是在描述一个问题。允许每两个方法同时运行(“读锁”),除了
    master()
    ,它排除了所有其他方法(“写锁”):


    我同意Mureinik的答案,但为了见鬼,这里有另一种方法可以设置读/写同步(未经测试):


    因此,当调用
    master
    时,
    foo
    不能被调用,而当调用
    master
    时,
    bar
    不能被调用?是的。但是可以同时调用
    foo
    bar
    (当然,假设不调用
    master
    )。所有方法是否仅针对
    master()
    同步,或者是否可以有其他组合?@BarryFruitman,多个线程是否应该能够调用
    foo()
    同时使用?谢谢,但正如我在最初的问题中所说,我希望避免这种方法,因为我实际上有三种以上的方法。我更喜欢这种方法,因为它只使用两个锁。@aioobe从rwLock开始,然后出于某种原因切换到
    rwl
    。愚蠢的打字错误,修正了。谢谢你的关注!隐马尔可夫模型。。这真的和OP想要的一样吗?如果
    foo
    应该是“同步的”,这意味着一次只有一个线程能够调用
    foo
    ,对吗?@aioobe
    foo()
    不需要单独同步;OP只想在运行
    master()。
    
    public class Test {
    
        private final Semaphore semaphore = new Semaphore(Integer.MAX_VALUE);
    
        public void master() {
            semaphore.acquireUninterruptibly(Integer.MAX_VALUE);
            try {
                //...
            } finally {
                semaphore.release(Integer.MAX_VALUE);
            }
        }
    
        public void foo() {
            semaphore.acquireUninterruptibly();
            try {
                //...
            } finally {
                semaphore.release();
            }
        }
    
        public void bar() {
            semaphore.acquireUninterruptibly();
            try {
                //...
            } finally {
                semaphore.release();
            }
        }
    
    }