簡體   English   中英

從另一個同步方法調用同步方法是否安全?

[英]Is it safe to call a synchronized method from another synchronized method?

如果synchronized方法調用另一個synchronized方法,它是否是線程安全的?

void synchronized method1() {
     method2()
}

void synchronized method2() {
}

是的,當您將方法標記為已synchronized ,您實際上是這樣做的:

void method1() {
    synchronized (this) {
        method2()
    }
}

void method2() {
    synchronized (this) {
    }
}

當線程調用進入從方法1方法2,那么它會確保它持有鎖到this ,它已經將,然后它可以通過。

當線程直接進入method1或method2時,它將阻塞直到它可以獲得鎖( this ),然后它將進入。

正如James Black在評論中所指出的那樣,你必須要了解你在方法體內所做的事情。

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

是一個標有同步調用方法的另一個同步方法線程安全。

一般來說,不可能說。 這取決於方法的作用,以及相同和其他類的其他方法。

但是,我們可以確保不同線程對同一對象的method1和method2的調用不會同時執行。 根據方法的作用,這可能足以說該類對於這些方法是線程安全的。

來自Java Tutorials站點http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

  1. 對同一對象的兩個同步方法的調用不可能進行交錯。 當一個線程正在為對象執行同步方法時,所有其他線程調用同一對象的同步方法(暫停執行)直到第一個線程完成對象。

  2. 當synchronized方法退出時,它會自動與同一對象的同步方法的任何后續調用建立一個before-before關系。 這可以保證對所有線程都可以看到對象狀態的更改

所以Java將確保如果2個線程正在執行相同的方法,那么這些方法將不會一個接一個地執行。

但是你需要了解Liveness問題, http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html

而且你是否在不經意地鎖定,導致你使用的代碼,它鎖定整個對象,如果你的對象只需要同步訪問一個變量,你應該鎖定該變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM