簡體   English   中英

搶占正在執行同步方法的線程

[英]Preempting a thread that is executing synchronized method

給出以下代碼

    class Test{
       double x;
       public void synchronized a()
       { 
          x = 0;
          //do some more stuff
       }
       public void b() 
       { 
          x = -1; 
       } 
    }

a() 中的線程能否在修改 x 的過程中被同一個 object 上調用 b() 的線程搶占?

同步方法不是像單個原子操作一樣執行嗎?

我相信另一種方式是可能的(b() 中的線程可以被在同一個 object 上調用 a() 的線程搶占,因為 b() 不受我的測試 object 鎖的保護)。

有人可以對此有所了解嗎?

synchronized僅阻止其他線程獲取相同的監視器。 絕不會使操作成為原子操作。 尤其是:

  • 該方法的副作用可以被其他未嘗試在同一監視器上同步的線程觀察到
  • 如果發生異常,則沒有任何回滾
  • 其他線程可以訪問和修改同步方法使用的相同數據,如果它們不在同一個監視器上同步

b()不同步,因此一個線程完全有可能同時執行a()而另一個線程同時執行b()

由於b()不是同步的,而a()是同步的,因此一個線程可能在a()中,而另一個線程在b()中。 因此,由於對x x值很可能會出現亂碼。

此外,如果您的代碼是這樣的:

class Test{
       double x;
       public void synchronized a()
       { 
          x = 0;
          //do some more stuff
       }
       public void b() 
       { 
          x = -1; 
          a(); //added call to a()
       } 
    }

並且你的兩個線程都在同一個實例上運行,那么就有可能線程 1 [當前在a()中被線程 2 [當前在b()中] 搶占。

但是在線程 1 被搶占后,由於線程 2 嘗試進入a()方法,JVM 將不允許它; 因為另一個線程[盡管不是正在運行的]已經鎖定了它。 因此,現在線程 2 將等待,直到線程 1 完成a()執行並返回。 然后線程 2 [最有可能] 將恢復活力並允許執行a()

暫無
暫無

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

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