同步重叠的方法集

Synchronizing overlapping sets of methods

设想一个 Java class 具有三种方法:

  1. master()
  2. foo()
  3. bar()

我想同步 master()foo() 以及 master()bar(),而不同步 foo()bar()。可以为每对同步方法设置一个单独的锁,但我的实际代码有三个以上的方法,所以我希望有一种方法可以在没有这么多锁对象的情况下做到这一点。

您可以在任何 Object 上使用 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) {
            ...
        }
    }
}

您实际上是在描述 ReadWriteLock。每两个方法都允许同时运行(一个"read lock"),除了master(),它排除了所有其他方法(一个"write lock"):

public class MyClass {
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Lock r = rwLock.readLock();
    private final Lock w = rwLock.writeLock();

    public void master() {
        w.lock();
        // do stuff
        w.unlock();
    }

    public void foo() {
        r.lock();
        // do stuff
        r.unlock();
    }

    public void bar() {
        r.lock();
        // do stuff
        r.unlock();
    }
}

我会同意 Mureinik 的回答,但只是为了它,这是另一种设置 read/write 同步(未经测试)的方法:

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

}