簡體   English   中英

為什么這些同步方法不斷給我不同的輸出?

[英]Why do these synchronized methods keep giving me different outputs?

我需要這些可以訪問相同數據的線程同時執行而不會相互混淆,所以我一直在嘗試使用同步方法而不是使用Thread.join() 問題是我根本看不到任何變化,它一直給我使用它們之前的相同結果。 我什至不知道我到底做錯了什么,同步方法應該阻止其他同步方法在完成之前執行,對嗎? 希望你能給我一些關於正在發生的事情的線索。

public class ThreadSync{
    public static void main(String[] args) throws InterruptedException {
         //if execute properly  
         //output can't be other than 0
         while(true) {
         ChangeValue counter = new ChangeValue();
         Threads t  = new Threads(counter,"up");
         Threads t2 = new Threads(counter,"down");
         Threads t3 = new Threads(counter,"print");
         t.start();
         t2.start();
         t3.start();
         }
    }
}
class Threads extends Thread{
    Threads(ChangeValue obj, String act){
        counter = obj;
        action = act;
    }
    @Override
    public void run() {
        switch(action) {
        case ("up"):    counter.up();    break;
        case ("down"):  counter.down();  break;
        case ("print"): counter.print(); break;     
        }
    }
    ChangeValue counter;
    String action;
}
class ChangeValue{  
    public synchronized void up()    { value++; }
    public synchronized void down()  { value--; }
    public synchronized void print() { System.out.println(value); }
    public int value = 0;
}

同步只是確保方法不會同時執行。 但是,它不保證任何執行順序。

您需要確保在其他線程終止之前不執行print() 這可以通過連接線程來實現。 為此,執行

t.join();
t2.join();

在啟動打印線程之前或在執行其邏輯之前。

請注意,同步仍然是明智的,因為它確保增量和減量操作以原子方式執行。 也就是說,執行count++時的讀取、遞增和寫入count是一次執行的(另請參閱: Why is i++ not atomic? )。 因此它阻止了以下執行順序:

  • [線程“向上”]:加載值為0count
  • [線程“向下”]:加載值為0count
  • [線程“向上”]: count遞增到1
  • [線程“向下”]: count遞減為-1
  • [線程“向上”]:存儲值為1count
  • [線程“向下”]:存儲值為-1count

(這是數據庫術語中的“丟失更新”。)

synchronized防止您的線程同時訪問該字段,但當然它不能保證線程執行的順序。 例如,如果純屬偶然,“Up”線程首先執行,“Print”線程第二,“Down”線程最后執行,則 output 將為 1,即使在所有線程完成后計數器值為 0。

暫無
暫無

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

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