2011-03-30 229 views
9

如果我有一個同步的公共方法和私有方法:同步方法

public synchronized void doSomething() { 
    doSomethingElse() 
} 

private void doSomethingElse() { 
} 

我需要同步的私有方法?

+2

取決於你希望他們做什麼,以及他們是否應該被允許同時運行。 – 2011-03-30 18:10:57

回答

1

從同步方法(或從​​塊中調用)中調用的任何方法仍在同步時運行。如果僅從同步方法調用私有方法,則不需要單獨同步。

4

編號:如果調用的唯一方法是doSomethingElse()是通過另一個同步的方法。

可能是:如果您以其他方式調用doSomethingElse(),通過一種不同步的方法,並且您需要保護它免受併發訪問。

0

如果您同步一段代碼,那麼從該代碼塊(在同一個線程中)調用的任何內容仍然保持初始鎖定。因此doSomethingElse在從doSomething調用時仍是同步塊的一部分。

如果你做的事:

public synchronized void doSomething() { 
    new Thread() { 
    public void run() { 
     doSomethingElse(); 
    } 
    }.start(); 
} 
private void doSomethingElse() { 
} 

然後doSomethingElse有被doSomething獲取鎖。

也避免了同步方法,因爲它暴露了併發策略的實現細節。查看同步(本)/同步的方法這個問題:Avoid synchronized(this) in Java?

如果doSomethingElse必須同步,無論它是否是從doSomething調用,它不會傷害到同步doSomethingElse爲同步鎖重入(即,如果一個線程已經鎖定了一個對象,它可以再次獲得鎖)。

0

個人而言,我不喜歡同步方法。我喜歡用某種鎖varaible的同步,像這樣:

private final Object lock = new Object(); 

public void doSomething() { 
    synchronized(lock) { 
    // Do some safely 
    doSomethingElse(); 
    } 
    // Do some work un-safely 
} 

private void doSomethingElse() { 
    // Do some work safely because still in lock above 
    // ... 
} 
5

這取決於你在做什麼。你需要確保連續訪問doSomethingElse()

如果是這樣,並且唯一呼叫doSomethingElse()的是doSomething(),那麼不,您不需要同步。但如果其他方法可以調用doSomethingElse(),那麼是的,你應該同步它。

13

這取決於:

  • 如果doSomethingElse是安全的,同時打電話,那麼你不需要​​。
  • 如果不是,那麼答案取決於它是從哪裏叫:
    • 如果只能從其他​​方法調用,那麼它並不需要是​​(但將其標記爲遺囑不要傷害);
    • 如果它可以從不是​​本身的方法調用,那麼它必須必須是​​。
0

雖然你做了什麼是好的,在我看來,同步應該以最低的粒度可能完成。這將建議同步實際的私人功能。目前,您假設類中沒有其他函數會獨立調用私有函數。這可能不是未來的情況。

2

這是@GuardedBy註釋的意圖。如果你期望一個鎖必須調用該方法時舉行,與註釋,並鎖(在本例中的名稱將是:

@GuardedBy("this") private void doSomethingElse() {…} 

然後你可以檢查不變的是真實的與FindBugs的。

您還可以使用other net.jcip.annotations描述它的線程安全或缺乏,並有FindBugs的驗證這些假設了。當然,the book需要插件也是如此。

0

即使代碼工作當私有方法不同步時正確hronized,從可維護性的角度來看,使私有方法同步似乎是謹慎的。

內部鎖是可重入的,將synchronized關鍵字添加到私有方法並沒有什麼壞處。

將代碼放在一個私有方法中會讓其被其他方法調用,所以在將來可以使用另一個不需要同步的方法調用私有方法時,這將是有意義的。