如果同步方法調用另一個同步方法,它是否線程安全?從另一個同步方法調用同步方法是否安全?
void synchronized method1() {
method2()
}
void synchronized method2() {
}
如果同步方法調用另一個同步方法,它是否線程安全?從另一個同步方法調用同步方法是否安全?
void synchronized method1() {
method2()
}
void synchronized method2() {
}
是的,當你方法標記爲,那麼你真的這樣做:
void method1() {
synchronized (this) {
method2()
}
}
void method2() {
synchronized (this) {
}
}
當線程調用進入從方法1方法2,那麼將確保其持有的鎖this
,它已經,然後它可以通過。
當線程直接進入method1或method2時,它會阻塞,直到它可以獲得鎖(this
),然後它將進入。
正如詹姆斯布萊克在評論中指出的那樣,你必須知道你在方法體內做了什麼。
private final List<T> data = new ArrayList<T>();
public synchronized void method1() {
for (T item : data) {
// ..
}
}
public void method3() {
data.clear();
}
突然,因爲你是在你的未來尋找一個ConcurrentModificationException
因爲method3
是不同步的它不是線程安全的,因此可以通過線程A,而線程B在method1
工作進行調用。
我試圖回答一個幾乎與此處提問相同的問題。這是2個可能的答案(其他2個說不會運行),這是正確的? C. \t該代碼將運行,但有潛在的死鎖情況 D. \t代碼將運行良好,因爲Java提供了可重入同步,使線程可以多次獲取相同的鎖-----我猜測它是D,但也許潛在的死鎖情況依賴於方法體? – 2015-05-10 01:35:26
@ user3140993這裏的代碼沒有死鎖的機會。 'method3'顯示不安全的線程操作,但是您關注的是重入同步。 – pickypg 2015-07-28 02:49:48
從Java教程網站http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
這是不可能的同一對象的同步方法交錯兩個調用。當一個線程正在執行一個對象的同步方法時,所有其他線程調用同一對象的同步方法塊(掛起執行),直到第一個線程完成對象。
當一個同步方法退出時,它會自動與同一對象的任何後續調用同步方法建立一個前後關係。這保證了更改對象的狀態是可見的所有線程
所以Java將確保如果兩個線程都在執行同樣的方法,該方法不會consurrently但接二連三執行。
但是你需要知道的活躍度的問題,http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html
而且也不管你是鎖定uncessarily,原因在您使用這個,它鎖定了整個對象的代碼,如果你的對象只需要同步訪問一個變量,你應該只鎖定該變量。
@Stephen Lee - 你不能鎖定一個變量。然後你說'synchronized(this.someVar)'你正在查看引用保存在'someVar'中的對象。區別非常重要。 – 2011-04-27 02:43:41
是一種用synchronized調用另一個同步方法線程安全的方法。
一般來說,這是不可能說的。它取決於方法的作用,以及同一類和其他類中的其他方法。
但是,我們可以確定,由不同線程創建的同一個對象上的method1和method2調用不會同時執行。根據這些方法的作用,這個可能是就足以說這個類對於這些方法是線程安全的。
這篇文章有幫助嗎,或者你困惑在哪裏? http://kalyanchakravarthy.net/?p=413 – 2011-04-27 02:23:18
是的 - 您實際上並不需要將method2標記爲synchronized,假定它只在上面給出的上下文中調用。 – debracey 2011-04-27 02:23:52
另外,它是否是線程安全的將取決於兩種方法中發生的情況。例如,如果他們調用非線程安全列表,那麼如果其他線程可以修改該集合,則它們可能不是線程安全的。 – 2011-04-27 02:24:20