2016-08-22 85 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

相關問題