簡體   English   中英

當兩個線程同時調用相同的靜態方法時會發生什么?

[英]What happens when two threads call the same static method at the same time?

當兩個線程同時調用相同的靜態方法時會發生什么? 例如:

public static String someMethod(){

    //some logic, can take about 1 second to process

    return new String(result);
}

第一個線程現在調用someMethod()。 第二個線程從現在起0.5秒后調用someMethod()(第一個線程仍在處理數據)。

我知道someMethod()可以同步。 但如果不同步會發生什么?

調用方法時,JVM會在執行線程中為調用創建堆棧幀 此框架包含方法中聲明的所有局部變量。 在任何不訪問字段的方法(靜態或其他方法)的情況下,每個執行在每個線程上完全獨立地進行。 如果該方法在其計算中使用參數,則這些參數也位於堆棧幀中,並且多個調用不會相互干擾。

這取決於你的方法是否改變了外部狀態。

static long i = 0l;
public static String someMethod(){
    String accm = "";
    for(;i < Integer.MAX_VALUE*20/*Just to make sure word tearing occurs*/; i++)
        accm += i
    return accm;
}

會引起問題:

  • 不保證多頭可以原子設置,因此它們可能會被“撕裂”( 規格
  • ++不是原子操作。 它與{int n = i; i = i + 1; return n}完全相同{int n = i; i = i + 1; return n} {int n = i; i = i + 1; return n}
    • i = i + 1也不是原子的,如果它在中間變化,則會重復一些值
    • n的返回可能是陳舊的

但如果i是一個局部變量,就沒有問題。 只要任何外部狀態在被讀取時保證是不可變的,就永遠不會有任何問題。

該方法是靜態的這一事實無關緊要。 他們的問題應該是有問題的代碼正在操縱哪些狀態變量

  • 如果沒有讀/寫任何實例/類的成員,那么應該沒有問題。
  • 在寫操作的情況下,需要某種同步
  • 如果只有讀取,則不一定意味着該方法很好地同步。 這取決於數據的寫入方式和線程。 例如,如果代碼讀取在寫操作期間受監視器M保護的V,則V的讀取也必須在同一監視器上同步。

如果兩個語句在不同的線程中執行,則無法保證第一個線程更改對第二個線程是可見的,除非您通過使用給定的同步策略同步someMethod()來建立這兩個語句之間的先發條件關系。 換句話說,如果要寫入相同的變量然后同時從兩個線程讀取,那么您的邏輯可能會產生意外和不可預測的結果。

暫無
暫無

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

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