java - 线程安全类 许多方法 ReentrantLock

标签 java multithreading

我有一个 Controller 类如下:

public class Controller {
    private Driver driver;

    public void method1() {/**/}
    public void method2() {/**/}
    public void method3() {/**/}
}

每个方法都使用驱动程序 来执行某些操作。然而,method2 是一个运行时间较长的进程并且需要锁定 driver,因为如果其他方法使用 drivermethod2 正在运行,然后会发生错误。

现在按照我目前的设置方式,我在 Controller 的调用类中实现了一个具有公平调度的ReentrantLock,它负责线程安全,如下所示:

public class Caller {
    private static final Lock LOCK = new ReentrantLock(true);

    private Controller controller;

    public void startStuff() { // Runs in multiple threads.
        ...
        ...
        LOCK.lock();
        try {
            controller.method1();
        } finally {
            LOCK.unlock();
        }
        ...
        ...
        LOCK.lock();
        try {
            controller.method2();
        } finally {
            LOCK.unlock();
        }
   }
}

相反,我想让 Controller 类线程安全,而不是让任何调用类处理它。我假设要完成的方法是在每个方法的开头和结尾实现 try-finally block ,但我在类中有大约 15 个方法。这真的是这样做的方法吗?这似乎是一大堆样板代码:

public class Controller {
    private static final Lock LOCK = new ReentrantLock(true);
    private Driver driver;

    public void method1() {
       LOCK.lock();
       try {
           /**/
       } finally {
           LOCK.unlock();
       }
    }
    public void method2() {
       LOCK.lock();
       try {
           /**/
       } finally {
           LOCK.unlock();
       }
    }
    public void method3() {
       LOCK.lock();
       try {
           /**/
       } finally {
           LOCK.unlock();
       }
    }
}

我不能只将 synchronized 添加到每个方法,因为我需要公平调度应用程序才能工作,并且使用 ReentrantLock 可以完美地工作。

如何使用 ReentrantLock 使 Controller 类成为线程安全的?

最佳答案

您可以将锁定代码包装到一个 block 中,并将实际的代码实现传递给它,这样您就可以删除重复/样板。类似于以下内容(Java 7):

public void method1() {
   withLock(new LockableMethod() {
       public void run() {
           /** your method1 code here **/
       }
   });
}

private void withLock(LockableMethod lockableMethod) {  
   LOCK.lock();
   try {
       lockableMethod.run();
   } finally {
       LOCK.unlock();
   }
}

如果您使用的是 Java 8,则只需传入 Lambda 即可删除更多样板文件:

public void method1() {
   withLock(() -> { 
           /** your method1 code here **/
       }
   );
}

private void withLock(Consumer<T> consumer) {
    LOCK.lock();
    try {
        consumer.accept();
    } finally {
        LOCK.unlock();
    }
}

关于java - 线程安全类 许多方法 ReentrantLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27744529/

相关文章:

java - 使用 JSoup 提取表数据

Java颜色碰撞检测

java - 如何传入/使用.Class/Object作为方法参数

python - 如何从 Python 中的运行中调用 Thread 派生类方法?

multithreading - 使用来自多个 kafka 主题的消息的最佳实践是什么?

multithreading - 从 Qt 中的其他线程发出信号时出现段错误

java - 守护线程不止一个?

c++ - 为什么 std::lock() 在使用我自己的 unique_lock 对象时会导致无限循环?

java - 如何将 JUnit Ant 任务配置为仅在失败时生成输出?

java - getArray 上的 SQLFeatureNotSupportedException