2010-11-19 62 views
5

我看到这一点:这样好吗?同步(线程),那么线程= NULL在同步块

// 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代码。

+1

是否有任何理由你没有使用Thread.interrupt(),因为这是由底层库支持的? – 2010-11-19 17:51:26

回答

7

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

Java语言规范的Section 14.19是不是这实际上明确的,但它确实状态的表达在开始评估 - 并没有提及以后再评价它。

+0

这很好,但是将线程引用设置为null是个不错的主意。 – Adamski 2010-11-19 16:08:41

+1

@Adamski:我倾向于采取一个相当强烈的观点,我首先要实现同步 - 我认为我会避免进入:) – 2010-11-19 16:10:31

+0

同意 - 事实上IntelliJ在这种情况下警告我关于同步一个非最终变量。 – Adamski 2010-11-21 22:15:44

3

有一个区别:

synchronized(this.thread) 

您在对象场同步this.thread

this.thread = null; 

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

0

你可以做到这一点,但几乎可以肯定的是,无论它试图达到什么目的,代码都是错误的。发布整个代码,我保证它显然是程序员不理解并发性。

请勿重新分配用于同步的变量。

0

如果您还有一个向线程分配新值的块,则只会出现问题。在这种情况下,你有一个竞争条件,因为两个块不锁定在同一个对象上,但会更新同一个字段,并且它将随机选择哪个块最后分配值。

1

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

+0

“评估”入境。 – EJP 2010-11-19 23:55:05

+3

@EJP多于评估 - 评估为null的表达式不会导致NullPointerException。 – 2010-11-20 07:52:16