【问题标题】:Sychronizing run() method of thread object同步线程对象的run()方法
【发布时间】:2016-06-02 03:22:36
【问题描述】:

注意:不要同步线程对象的 run() 方法,因为 出现多个线程需要执行 run() 的情况。因为 那些线程试图在同一个对象上同步,只有一个 一次线程可以执行run()。结果,每个线程都必须等待 前一个线程在可以访问 run() 之前终止。

发件人:http://www.javaworld.com/article/2074318/java-concurrency/java-101--understanding-java-threads--part-2--thread-synchronization.html?page=2

同一个Thread对象的run()如何执行不同的线程?

【问题讨论】:

  • 一般来说,如果你看到黄鼠狼的话(“情况出现”),这意味着这篇文章并不是那么好。从上下文中可以清楚地看出,它们确实意味着Thread 类的run(而不是你可能在线程之间共享的Runnable)。在多个线程之间共享Thread 实例会非常奇怪,所以我根本没有看到文章中那个标注的意义。 (当然,这也意味着同步 run 没有多大意义,与 within run...的离散工作单元相反)
  • @T.J.Crowder 你能说明下同一Thread 对象的Thread::run() 是如何被不同的线程调用的吗?
  • 记住Thread 实现RunnableThread 的构造函数之一接受Runnable 并从Threadrun 调用它的run。所以:Thread t1 = new Thread(); Thread t2 = new Thread(t1); t1.start(); t2.start(); 现在他们都在运行t1run 方法。
  • @TJCrowder,这种奇怪的模式(或类似的东西)可以在许多菜鸟的问题中找到.

标签: java multithreading synchronized java-threads


【解决方案1】:

关于同步的一些一般建议似乎与此处相关:不要将同步放在线程或可运行文件中,将其放在线程正在访问的数据结构中。如果您用锁保护数据结构,那么您可以确保没有线程可以以不安全的方式访问它,因为数据结构正在强制执行安全访问。如果您将同步留给线程,那么有人可以编写一个不进行适当锁定的新线程,并可能破坏正在访问的数据结构。请记住,同步的重点是保护数据免受不安全的并发修改。

(如果您查看 JavaWorld 文章,清单 2 和清单 3 说明了这一点;清单 3 明显比清单 2 更明智,因为 FinTrans 数据正在保护其自身的完整性,而清单 2 中的线程正在执行同步。作者认为因为清单 3 具有更好的锁定粒度,并且没有解决让数据结构保护其自身完整性的问题。也许那是因为他正在制作玩具示例并且没有那么认真地对待它们中的任何一个;毕竟,在他使用字符串作为锁显示的页面顶部,这是一个非常糟糕的主意。)

Java API 文档也不鼓励您使用 锁定线程对象。 Java 线程实现会锁定线程,例如在加入线程时,因此您所做的任何操作都可能与 Java 线程 API 的功能纠缠在一起;例如,如果您尝试锁定线程,您发出的任何通知调用都可能被其他尝试加入的线程消耗掉。此外,您可能会看到一些奇怪的事情,例如当一个线程终止时,它会向任何在其监视器上等待的东西发送通知。如果使 Thread 子类的 run 方法同步,则​​正在运行的线程必须获取自己的锁。如果另一个线程想要加入它(除非子类 Thread 通过等待放弃锁),这使得任何线程都无法加入(因为这涉及等待,这需要获取 Thread 对象上的锁),所以而不是加入线程短暂地获取锁并稳定下来等待,加入线程很可能会在waitset中挂起,争夺锁,直到待加入线程终止。

另一点是最好将任务实现为 Runnables 而不是 Thread 对象。我想不出实现 Thread 对象的 run 方法比实现 Runnable 更可取的情况,除非我试图故意制造一个令人困惑的情况,或者正在输入一个又快又脏的演示。 (我真的很想知道 Thread 实现 Runnable 的原因是否是为了让人们更方便地编写 fast-n-dirty 演示代码。)让你的任务成为 Runnable 可以清楚地表明你有一些不受约束的逻辑作为一个新线程运行,但也可以将其移交给一个执行者,该执行者可以负责该任务的执行方式。 (您可以使用 Thread 对象来执行此操作,但这会令人困惑。)因此,不在 Thread 对象上创建同步运行方法的另一个原因是,您不应该将 Thread 子类化以覆盖 run 方法(通常它是通常最好使用带有 Runnables 的执行器而不是启动你自己的线程)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多