簡體   English   中英

同步方法在停止一個線程與另一個線程之間的重要性是什么?

[英]What is the importance of synchronized method in stopping one Thread from another?

從《有效的Java》一書中,我遵循了著名的代碼來停止另一個線程的運行

 public class StopThread {
     private static boolean stopRequested;
     private static synchronized void requestStop() {
          stopRequested = true;
     }
     private static synchronized boolean stopRequested() {
          return stopRequested;
     }
     public static void main(String[] args)
                            throws InterruptedException {
          Thread backgroundThread = new Thread(new Runnable() {
               public void run() {
                   int i = 0;
                   while (!stopRequested()) {
                       i++;
                   }
               }
          });
          backgroundThread.start();
          TimeUnit.SECONDS.sleep(1);
          requestStop();
     }
}

一條線是寫有那就是“ 同步沒有影響,除非同時讀取和寫入操作是同步的。”但很顯然,如果我們不使用synchronized關鍵字與方法requestStop的代碼將正常工作,也就是說,它幾乎結束后需要1秒。這里還有一件事是,如果我們不同步兩種方法,由於代碼優化,我們將(最有可能)進入無限循環。所以我的問題是:-
1.如果不同步“ stopRequested”方法,在什么情況下以及在什么情況下會出錯?盡管在這里,如果不同步,程序將按預期運行,即,幾乎在1秒內終止。
2.Does synchronized關鍵字強制執行VM每次停下優化?

1.如果不同步“ stopRequested”方法,在什么情況下以及如何會出錯?

假設一個線程正在寫入(更新) stopRequested字段,現在在第一個線程從requestStop()更新stopRequested的值之前,另一個線程可以通過調用stopRequested()來讀取stopRequested的值(如果stopRequested()同步) 。因此它將無法獲得更新的值。

2. synced關鍵字是否強制VM每次停止優化? 並非總是如此,從JDK6U23實現的Escape Analysis也參與其中。 同步會創建一個內存屏障,以確保事前發生關系。 也就是說,在同步塊之后執行的任何代碼塊都必須具有更新后的值(反映出之前所做的更改)。

如果事前保持良好,則可以在同步塊內無序執行語句以提高效率。 另一方面,如果JVM確定某個同步塊只能由單個線程訪問,則可以將其刪除。

線程對變量所做的更改不一定會立即被其他線程看到。 在此處使用同步可確保一個線程的更新對另一線程可見。

1)該更改可能對其他線程不可見。 在沒有同步,易失性或原子字段的情況下,無法保證其他線程何時會看到更改。

2)synced關鍵字可以幫助VM決定指令重新排序的限制以及VM可以優化的內容。

在計算機上進行測試不一定會顯示與使用具有更多處理器的服務器相同的結果。 不同的平台可能會做更多的優化。 因此,僅僅因為它可以在您的計算機上運行並不意味着就可以了。

1.如果不同步“ stopRequested”方法,在什么情況下以及在什么情況下會出錯?盡管在這里,如果不同步,程序將按預期運行,即,幾乎在1秒內終止

如果JVM決定在backgroundThread的run方法中優化代碼,則事情可能會出錯。 JVM可以對stopRequested()的讀取進行重新排序以進行優化,因為它可能永遠不會再調用stopRequested()方法。 但是現在,幾乎所有的JVM實現都可以解決這個問題,因此無需進行stopRequested即可,因為您的代碼可以同步運行。 還要注意的是,如果不使stopRequested同步,則其他非同步線程可能不會立即看到對stopRequested布爾變量所做的更改。 只有使用了同步,其他線程才能立即檢測到任何更改,因為進入同步方法將清除緩存並從內存中重新加載數據。 在高度並發的系統中,立即檢測內存變化非常重要

2)sync關鍵字是否強制VM每次停止優化?

Synchronized關鍵字不會強制VM停止優化,但可以使其遵循以下所列內容。 VM仍可以進行優化,但必須注意以下事項。 同步有效地執行以下操作:

  1. 它保證在關系發生之前發生。 如果一個動作發生在另一個動作之前,則第一個動作對第二個動作可見,並在第二個動作之前排序。

  2. 它保證了內存可見性,即在同步塊退出之前立即清除了可能緩存的塊中所做的所有修改,這導致任何其他同步線程立即看到內存更新。 對於高度並發的系統,這將很重要。

只是使stopRequested易變。 然后,方法stopRequest不必同步,因為它不會更改任何內容。

暫無
暫無

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

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