【问题标题】:Is this ok? Synchronized( thread ), then thread=null in the synch block这个可以吗?同步(线程),然后在同步块中 thread=null
【发布时间】:2010-11-19 16:04:55
【问题描述】:

我看到了:

// thread is a member of this class

synchronized( this.thread )
{
  this.thread.running = false;
  this.thread.notifyAll(); // Wake up anything that was .waiting() on
  // the thread
  this.thread = null;  // kill this thread reference.
  // can you do that in a synchronized block?
}

是否可以设置thread=null 同时仍保持锁定?

我在一些 BB 代码中发现了这个金块。

【问题讨论】:

  • 有什么理由不使用 Thread.interrupt() 因为底层库支持?

标签: java blackberry synchronized-block


【解决方案1】:

是的,没关系。同步语句将获取它锁定的引用的副本,并使用该副本来计算最后要解锁的内容。

Java 语言规范的

Section 14.19 实际上并不清楚这一点,但它确实声明表达式在开始时被评估 - 并且没有提到稍后再次评估它。

【讨论】:

  • 没问题,但是将线程引用设置为null是否是个好主意值得怀疑。
  • @Adamski:老实说,我倾向于对我首先同步的内容持相当强烈的看法 - 我想我会避免进入那个:)
  • 同意 - 事实上 IntelliJ 在这种情况下会警告我在非最终变量上同步。
【解决方案2】:

有区别:

synchronized( this.thread )

您正在对象上同步字段this.thread 指向的对象

this.thread = null;

您正在重新分配该字段。你没有对上面引用的对象做任何事情,所以锁仍然有效。

【讨论】:

    【解决方案3】:

    同步表达式在进入时被取消引用,因此该锁的任何后续用户都将收到 NullPointerException。你可以通过在同步块之前放置一个空检查来解决这个问题,但是你已经引入了一个竞争条件。

    【讨论】:

    • @EJP 超过评估值 - 评估结果为 null 的表达式不会导致 NullPointerException。
    【解决方案4】:

    你可以做到,但几乎可以肯定,无论它试图实现什么,代码都是错误的。贴出整个代码,我保证明显是程序员不懂并发。

    不要重新分配用于同步的变量。

    【讨论】:

      【解决方案5】:

      只有当你还有一个为线程分配新值的块时,你才会遇到问题。在这种情况下,您会遇到竞争条件,因为两个块不会锁定同一个对象,而是会更新同一个字段,并且哪个块最后分配值是随机的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-30
        • 1970-01-01
        • 2016-09-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多