【问题标题】:Cascading synchronization with Java与 Java 级联同步
【发布时间】:2011-05-07 10:27:29
【问题描述】:

我非常努力地搜索有关该问题的信息,但没有任何相关信息。 任何贡献将不胜感激。

DataStructure ds = new DataStructure();
public synchronized void run() { b(); }
private void b() { ds.update(); }
public synchronized void c() { ds.update(); }

假设上面的代码是使用线程实现的。 您可能会注意到,有一个 DataStructure 对象正在通过同步方法共享和访问,而在任何给定时间只能调用一个同步方法(我没记错。对吗?)。 是否有可能通过公共方法以不同步的方式访问 DataStructure 对象?

谢谢。

【问题讨论】:

  • 你为什么不从run()打电话给c()
  • b() 只是 run() 应该做的一小部分,这就是设计看起来像这样的原因。
  • 所以b() != c() ?另外,你为什么不synchronize (ds),因为它实际上是你想要保护的ds
  • 你的 run() 中是否有一个 while 循环?

标签: java multithreading data-structures synchronization


【解决方案1】:

您的代码不完整,但如果上述代码是RunnableThread 的一部分,那么由于您正在同步整个run() 方法,因此给定方法不可能并发。在这种情况下,使用线程毫无意义。

我也看不到 DataStructure 将在线程之间共享的位置 - 看起来像是为每个线程创建了一个单独的。如果它实际上是共享的,那么访问将不会同步,因为您在 RunnableThread 而不是共享对象上同步。

【讨论】:

  • 感谢您的回复,能否请您阅读下面的答案,看看您是否可以提供帮助?
  • @JavaNewbie:我同意 Chii 的观点,我们没有足够的信息。而且我怀疑您看到的不是死锁,而是同步 run() 方法的效果——这意味着如果其他线程调用 c(),它们将阻塞,直到该线程完成执行。现在,如果您有两个这样的线程互相调用 c(),那将是一个死锁。
【解决方案2】:

没有看到更多代码,很难说。这些方法属于什么类?它们是如何被调用的,被什么类调用?

并发问题很难诊断,如果没有足够的信息则更难诊断。

我假设您拥有的是执行上述 run() 方法的线程,并且有不同的线程执行 c() 方法。同步发生在上述方法所在的类上,所以不会有任何问题(如果有很多线程会很慢)。

【讨论】:

  • 您的假设是正确的,这正是调用方法的方式。奇怪的是,不知何故,我陷入了僵局。
  • @JavaNewbie:使用jstack 并查看死锁中涉及的线程的堆栈跟踪。
【解决方案3】:

如果

  1. 除了您在此处编写的,没有其他公共方法可以访问 ds,并且
  2. 您所说的“DataStructure 对象”是您的类的特定对象实例中的对象实例(而不是所有 DataStructure 对象)

那么您的期望是正确的。不应通过您的类的公共方法对 ds 进行任何并发访问。

老实说,我在您的课程中没有看到任何与普通同步方法示例不同的特别之处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    相关资源
    最近更新 更多