2016-08-22 90 views
1

所以在Java中,我知道你可以使用对象的所谓“固有锁定”来创建互斥区域,并确保内存可见性。 Java使得它特别容易隐含在this对象的一些语法糖的内部锁锁,如:在Java中使用Thread对象的内部锁定可以吗?

public class Foo{ 
    public synchronized doFoo(){ 
     //doFoo is executed in an implicit synchronized block 
     //on the 'this' object 
    } 
} 

这是可以理解和接受的做法看守许多对象的成员字段。我不知道是当锁定的对象是Thread对象时,上述情况是否正常。例如,是否有任何理由避免以下情况?

public class Bar extends Thread{ //notice the 'extends Thread' here 
    public synchronized doBar(){ 
     //doBar is executed in an implicit synchronized block 
     //on the 'this' object 
    } 
} 

现在,我要坚持我所知道的是更安全的东西,如:

public class Baz extends Thread{ //notice the 'extends Thread' here 
    private final Object explicitLockObject = new Object(); 

    public doBaz(){ 
     synchronized(explicitLockObject){ 
      //doBaz impl 
     } 
    } 
} 

我的问题将得到双重使用选项#2(Bar为例):

  1. 是否有关于上可能与这样的锁定策略冲突的主题本身同步现有JVM代码或Java约定?
  2. 锁定this通常意味着该对象的访问应始终由该对象的内部锁保护。在Bar线程的情况下,这意味着我们暗示只要您触摸Bar线程,就应该在实例上进行同步。这似乎可能导致一些其他线程不必要地(甚至危险地)阻塞,直到Bar完成/退出。

以上是有效的担忧吗?我觉得我需要这样一个布赖恩戈茨灯塔:-)

+3

1.嗯,有一个惯例,你不应该首先扩展'Thread':实现一个'Runnable',将它作为构造函数参数传递给'Thread'(参见[this question](http ://stackoverflow.com/questions/541487/implements-runnable-vs-extends-thread))。现在,你会关心在'Runnable'上同步吗? –

+0

是的,我知道那个约​​定。说实话,这本来不是我的代码,我也不打算重构。我知道'Runnable'会很好,因为它没有州行李。可惜!这不是我所拥有的,我很想知道这个答案。 – codeCogs

+1

我建议开发人员更喜欢并发包中的新类,而不要使用原始线程。多线程代码很难编写。 – duffymo

回答

2

...有没有什么理由避免[锁定Thread实例]?

所以,如果你看一下Thread类,你可以看到有许多实例​​方法。它们包括:

  • start()
  • stop()(不建议使用)
  • join(long)(从join()调用)
  • join(long, int)

这似乎是它最终可能会造成一些其他线程阻止不必要的(甚至危险),直到Bar完成/退出。

对,任何调用上述方法的人都会用其他​​方法阻塞。显然只有join(...)方法实际上会成为一个问题,他们不应该返回,直到Thread完成任何。

javadocs for Thread.join(...)指出:

作为一个线程终止 this.notifyAll()方法被调用。建议 应用程序在Thread实例上不使用wait(),notify()notifyAll()

我在Thread源代码的任何地方都看不到关于​​的任何警告。

而且遍览ThreadPoolExecutor表明,它至少不synchronizeRunnableCallable情况下,这将是非常糟糕,所以至少有一个标准ExecutorService你应该不错。

所以我想简短的回答是,虽然它可能不建议,在捏的同步Thread应该工作。正如你所提到的那样,最好是执行Runnable并锁定它,而不是扩展Thread

希望这会有所帮助。

+1

非常有帮助 - 我会考虑有关'wait()','notify()'等的警告是一些证据表明,使用Thread对象的多线程实用程序与使用其他任何Object的应用程序有点不同,但缺乏对内在显示器本身的警告确实表明它可能会好起来。 Upvoted,但我会留出几天的时间让某些人以一些明确地解决问题的来源/论据来突破,而不是依靠缺乏警告(何时文档完全完整:-))。如果没有人马上跳进来,我会标记为答案。 – codeCogs

相关问题