【问题标题】:Locking on static final object attribute vs locking code based on class type锁定静态最终对象属性与基于类类型的锁定代码
【发布时间】:2023-03-25 15:16:01
【问题描述】:

我在这里运行 safe1 方法时遇到了一些多线程问题:

    public class Test {

    private static final Object lock = new Object();

    public void safe1() {
        //Some non thread safe code
        synchronized (lock) {
            //Some thread safe code
        }
        //Some non thread safe code.
    }
    
    public void safe2() {
        //Some non thread safe code
        synchronized (lock) {
            //Some thread safe code
        }
        //Some non thread safe code.
    }
}

我认为它的行为与这段代码相同。

public class Test {

    public void safe1() {
        //Some non thread safe code
        synchronized (Test.class) {
            //Some thread safe code
        }
        //Some non thread safe code.
    }
    
    public void safe2() {
        //Some non thread safe code
        synchronized (Test.class) {
            //Some thread safe code
        }
        //Some non thread safe code.
    }
}

正确吗? 我想确保没有 2 个线程在 VM 范围内运行相同的“安全代码”。

【问题讨论】:

  • 取决于是否有其他代码尝试在同一个对象或类上同步。
  • @khelwood 你能详细说明一下吗?我有很多类型测试运行的实例。我想确保没有 2 个线程在 VM 范围内运行相同的“安全代码”。同步(锁)和同步(Test.class)一样吗?
  • 您是否有任何 other 代码执行 synchronized (Test.class) 或 Test 类上的同步静态方法,或 Test 类中使用 lock 对象的任何其他方法?如果是这样,那么safe1safe2 是不同的,因为它们将与不同的其他代码共享锁。
  • @khelwood 我还有其他几种使用同步(锁定)的方法。我没有混合同步的方法。所以真正的问题是:使用同步(lock)的一组方法是否与使用同步(Test.class)的一组方法相同。我将使用其中一种方法,而不是两种方法。
  • 如果所有代码都使用同一个锁,那么据我所知,锁是类还是对象并不重要。如果某些代码更改为使用不同的锁,而其他代码仍使用相同的锁,那么您将有不同的行为,因为共享锁的两件事与拥有不同锁的两件事不同。

标签: java multithreading locking monitor


【解决方案1】:

不同之处在于有人可以编写获取锁的代码

synchronized(Test.class) {

并且能够在不调用 Test 对象的方法的情况下获取锁。应用程序中的任何任意代码都可以获取锁,并可能阻止使用它的其他代码继续进行。锁定私有字段会使事情变得更加困难,代码必须通过反射获取私有字段,并且可以配置安全管理器来防止这种情况发生。

否则锁的作用域是相同的,你在整个类加载器的测试类的所有实例中一次允许一个线程。所以创建更多的测试实例对你的并发水平没有帮助。如果您正在保护实例数据,那么这似乎是不必要的限制。锁定范围应与您阻止并发访问的数据的范围相同。

如果 Test 类由两个不同的类加载器加载,那么您将拥有 Test 类的两个独立副本。 Test.class 在整个应用程序中是否唯一取决于应用程序如何使用类加载器。但就这一点而言,您的任何一种方法都不是可取的。

【讨论】:

    【解决方案2】:

    此代码不允许任何其他线程访问 jvm 的同一个类加载器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多