【问题标题】:Synchronized methods with independent shared variables具有独立共享变量的同步方法
【发布时间】:2020-06-30 20:04:44
【问题描述】:

我最近询问了 Java 中的同步方法是否共享同一个锁键。答案是肯定的。但我的下一个想法是,这种模式非常严格,可能会导致不必要的延迟。例如,假设我们有 2 个同步方法,每个方法处理不同且独立的共享变量。如果一个变量的处理不影响另一个变量,那么同时锁定这两种方法有什么意义?有没有办法处理这种情况?

【问题讨论】:

  • 肯定有。方法不止一种。屏幕右侧的“相关”块包含几篇解决这些问题的帖子。
  • 您的问题是关于锁定的粒度——任何给定的锁定保护了多少或多少数据。好消息是,粒度完全由您在编写程序时决定。您可以根据自己的目的使用尽可能多或尽可能少的不同锁定对象来保护您的数据。
  • Re,“锁定这两种方法有什么意义......?”不要考虑“锁定方法”。方法永远不需要被锁保护。 数据需要被锁保护。每当两个或多个线程可以同时访问相同的数据,并且其中至少有一个要更改数据时,那么数据可能应该被锁保护。

标签: java concurrency synchronized


【解决方案1】:

假设你有这个类:

class C {
    public synchronized void foo(...) { ... }
    public synchronized void bar(...) { ... }
    ...
}

假设你有:

final C c_0 = new C(...);
final C c_1 = new C(...);

foo()bar() 都是synchronized 这一事实不会阻止一个线程调用c_0.foo(...) 而另一个线程同时调用c_1.bar(...)。事实上,它甚至不会阻止一个线程调用c_0.foo(...),而另一个线程调用c_1.foo(...)

所谓的“同步方法”

synchronized void foo(...) { ... }

真的只是语法糖:

void foo( ... ) {
    synchronized(this) {
        ...
    }
}

所以,如果一个线程调用c_0.foo(),它在c_0 实例上“同步”,如果另一个线程调用c_1.foo(),则该线程在c_1 实例上同步--a 不同 实例。

foobar 方法中的 synchronized 关键字仅在两个不同的线程都尝试同时操作同一个实例时才有意义。

【讨论】:

  • 我理解当我们有两个不同但我的意思是与一个对象有关时。
  • @nonlinearly,如果每个对象需要多个锁,则不要定义synchronized 方法。请改用synchronized blocks。同步方法是处理简单情况的简单方法,但简单方法并不总是最好的方法。
  • 让我明白你说的。你说如果我们在块中使用同步语句,那么每个语句会有不同的锁键,但是当我们在方法中使用同步时,每个方法都会有相同的一个键?
  • @nonlinearly,当您编写synchronized 块时,您可以选择任何您想成为锁定对象的对象。但是,当你写一个synchronized方法时,它的锁对象只能是调用该方法的实例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-27
  • 2015-10-17
  • 1970-01-01
  • 2018-06-11
相关资源
最近更新 更多