java 同步访问不同的临界区

java synchronizing access to different critical sections

我有一个如下所示的方法。

public class CriticalSections
{

    public void mainMethod(boolean b)
        {
            if (b) {
                method1();
            }
            else {
                criticalMethod();
                method2();
            }
        }


        private void criticalMethod()
        {
            System.out.println("in criticalMethod");
        }

        private void method1()
        {
            System.out.println("in method1");
        }

        private void method2()
        {
            System.out.println("in method2");
        }
 }

我需要限制对这些方法的访问,这样

  1. 当线程访问 criticalMethod() 时,对于所有其他 threads.Similarly 线程访问 method1() 和 method2() 时,应限制对 method1() 和 method2() 的访问,应限制所有其他线程访问 criticalMethod()。
  2. method1() 可以被不同线程单独并发访问。
  3. method2() 可以被不同的线程单独并发访问。
  4. method1() 和 method2() 可以被不同的线程同时访问。

为了满足第一个访问条件我想出了下面的代码, 但这不会满足其他 3 个条件,因此性能会受到影响。

public class CriticalSections
{

    private final Lock lock1 = new ReentrantLock();
    private final Lock lock2 = new ReentrantLock();
    private final Lock lock3 = new ReentrantLock();

    public void mainMethod(boolean b)
    {
        if (b) {
            lock1.tryLock();
            try {
                method1();
            }
            finally {
                lock1.unlock();
            }
        }
        else {
            lock1.tryLock();
            try {
                lock2.tryLock();
                try {
                    lock3.tryLock();
                    try {
                        criticalMethod();
                    }
                    finally {
                        lock3.unlock();
                    }
                }
                finally {
                    lock2.unlock();
                }
            }
            finally {
                lock1.unlock();
            }
        }
        lock3.tryLock();
        try {
            method2();
        }
        finally {
            lock3.unlock();
        }
    }

    private void criticalMethod()
    {
        System.out.println("in criticalMethod");
    }

    private void method1()
    {
        System.out.println("in method1");
    }

    private void method2()
    {
        System.out.println("in method2");
    }
}

应该使用什么同步机制来满足上述场景?

您需要的是对 criticalMethod 的独占锁和对方法 method1method2 的共享锁。实现此目的的最简单方法是使用 java.util.concurrent.locks.ReentrantReadWriteLock,如下所示:

public class CriticalSections {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();

    public void mainMethod(boolean b) {
        if (b) {
            method1();
        } else {
            criticalMethod();
            method2();
        }
    }

    private void criticalMethod() {
        Lock writeLock = lock.writeLock();
        writeLock.lock();
        try {
            System.out.println("in criticalMethod");
        } finally {
            writeLock.unlock();
        }
    }

    private void method1() {
        Lock readLock = lock.readLock();
        readLock.lock();
        try {
            System.out.println("in method1");
        } finally {
            readLock.unlock();
        }
    }

    private void method2() {
        Lock readLock = lock.readLock();
        readLock.lock();
        try {
            System.out.println("in method2");
        } finally {
            readLock.unlock();
        }
    }
}

如果你担心性能,你也可以take a look at java.util.concurrent.locks.StampedLock (Java 8+).