java - 如何确保两个线程访问相同的资源并使它们线程安全?

标签 java multithreading thread-safety race-condition

我是多线程新手,我有一些基本问题无法得到答案。假设我有一个名为 BankTransaction 的类,我想在其中处理多线程情况。

案例1(基于应用程序的单例)

@Singleton (Application based singleton)
class BankTransaction {
    synchronized void doSomeTransaction() {
        // write operation
    }
}

案例2(基于请求的单例)

@Singleton (Request based singleton)
class BankTransaction{
    synchronized void doSomeTransaction() {
        // write operation
    }
}

问题

请耐心等待,并用通俗的语言解释我,因为我需要把事情弄清楚。

  1. 在情况 1 中,如果 1000 个用户使用 BankTransaction 类的同一个实例(因为它是基于应用程序的单例)并使用 doSomeTransaction() 方法,那么这 1000 个用户中每个用户的请求会很慢吗?因为它是同步的并且可以线程安全的方式工作。所以,这是一个不好的做法。我的理解正确吗?

  2. 在情况 2 中,如果同样 1000 个用户正在使用 BankTransaction 类的 doSomeTransaction() 方法,每个用户都会获得自己的 BankTransaction 类实例,并且对于其中任何一个用户来说都不会很慢。但是,例如,在这 1000 个用户中,其中 2 个用户关系密切(丈夫和妻子),并且正在访问同一银行帐户并同时执行 doSomeOperation() 方法,那么我该如何处理竞争条件。我该如何处理这个问题?因为它们都有两个不同的 BankTransaction 类实例,并且会出现数据不一致的情况。

最佳答案

  1. 是的。你的理解是正确的。如果您不想允许多个用户更改对象的状态,则应该使方法同步。该示例可以是应用程序级配置对象。

  2. 现在,有很多解决方案。最简单的方法是将此问题推迟到某些 ORM 解决方案,该解决方案可以进一步使用记录级锁定技术或其他技术。但是,如果您想手动处理此问题,最简单的方法是在 db 中维护一列。现在,每次修改记录时,都应该增加该值。在提交记录之前,您应该检查该值是否与从数据库中获取的记录的值相同。如果相同,那么您可以确定自您开始交易以来没有人修改过它。但是,如果值不同,您可以向用户抛出错误,指出记录已被其他用户修改。

关于java - 如何确保两个线程访问相同的资源并使它们线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56412993/

相关文章:

java - 与 Runtime.exec() 的参数作斗争

c# - 当工作线程和UI线程调用同一方法(包括调用ui控件)时出现死锁

c++ - C++11 中的生产者-消费者

java - 在它的关键部分执行的线程可以在 Java 中被抢占吗?

java - Telegram 机器人 - 内联模式

java - Guice - 当您只知道接口(interface)时如何获取实例

java - 编码约定 : final class instance in CAPITAL_LETTERS?

c++ - 使用 mutex 和 condition_variable 时的异常

c# - C# 中的线程安全异步代码

java - 同步方法 - 这是如何工作的?