簡體   English   中英

java中多線程環境中的靜態方法行為

[英]Static method behavior in multi-threaded environment in java

有一個簡單的愚蠢問題困擾着我並在腦海中提出了幾個論點。 我想拋棄以下問題的所有疑慮。

class Clstest{

    public static String testStaticMethod(String inFileStr) {

        // section 0

        // section 1

        // do something with inFileStr

        // section 2

        // section 3

        return inFileStr;

    }

}

假設有五個線程同時執行對Clstest.testStaticMethod("arg-n")的調用。

線程1調用Clstest.testStaticMethod("arg-1")

當線程1在第1部分中時,線程2調用Clstest.testStaticMethod("arg-2")

那么線程1會發生什么? 它會進入睡眠狀態嗎?

當線程1獲得機會時,它會從暫停的第1部分恢復執行嗎?

當有一個Clstest.testStaticMethod並且所有五個線程之間共享相同的Clstest.testStaticMethod時,它是如何發生的?

是否有可能交換多個線程發送的inFileStr

Hans Passant的回答很好。 但是我想我會嘗試在一個稍微簡單的層面上解釋一下,遇到這個並且對Java來說很新的人。 開始..

java中的內存分為兩類 - 堆和堆棧。 堆是所有對象都存在的地方,堆棧是線程工作的地方。 每個線程都有自己的堆棧,無法訪問其他堆棧。 每個線程還有一個指向代碼的指針,指向它們當前正在運行的代碼位。

當一個線程開始運行一個新方法時,它會將該方法中的參數和局部變量保存在自己的堆棧中。 其中一些值可能是指向堆上對象的指針。 如果兩個線程同時運行相同的方法,則它們的代碼指針都指向該方法,並在其堆棧上擁有自己的參數和局部變量副本。 如果堆棧上的東西指向堆上的相同對象,它們只會相互干擾。 在這種情況下,可能會發生各種各樣的事情。 但正如漢斯指出的那樣,字符串是不可改變的(不能改變),所以如果這是唯一被“共享”的對象,我們就是安全的。

這么多線程可以運行相同的方法。 它們可能不會同時運行 - 它取決於您的機器上有多少核心,因為JVM將Java線程映射到OS線程,這些線程被調度到硬件線程上。 因此,在不使用復雜同步機制的情況下,您幾乎無法控制這些線程的交錯方式。

請注意,睡眠是線程對自身的影響。

它會進入睡眠狀態嗎?

不,運行線程不會影響其他線程,只要它們不會故意彼此同步。 如果您有多個處理器核心,所有最近的計算機都可以,那么這些線程可能會在同一時間執行。 由於您的機器可能沒有足夠的內核,因此當您啟動5個線程時,這種可能性會降低一些。 操作系統被迫在它們之間進行選擇,每個都給它們一些時間來運行。 線程調度程序的工作。 一個線程將不會處於“休眠”狀態,它只是暫停並等待線程調度程序給它一個運行的機會。 它將在調度程序中斷的地方恢復。

是否有可能交換多個線程發送的inFileStr?

沒有這種可能性,線程有自己的堆棧,因此任何方法參數和局部變量對於每個線程都是唯一的。 使用字符串還可以保證這些線程不會相互干擾,因為字符串是不可變的。

如果參數是對另一種可變對象的引用,則沒有這樣的保證。 或者,如果方法本身使用靜態變量或對堆上對象的引用。 當線程修改對象而另一個線程讀取它時,需要同步。 C#語言中的lock關鍵字是實現此類所需同步的樣板方法。 該方法是靜態的這一事實並不意味着永遠不需要這種同步。 不太可能,因為您不必擔心線程訪問同一個對象(共享 )。

暫無
暫無

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

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