![](/img/trans.png)
[英]Why is this simple Java synchronized code block example giving me different output, depending on which object I lock on?
[英]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? )。 因此它阻止了以下執行順序:
0
的count
0
的count
count
遞增到1
count
遞減為-1
1
的count
-1
的count
(這是數據庫術語中的“丟失更新”。)
synchronized
防止您的線程同時訪問該字段,但當然它不能保證線程執行的順序。 例如,如果純屬偶然,“Up”線程首先執行,“Print”線程第二,“Down”線程最后執行,則 output 將為 1,即使在所有線程完成后計數器值為 0。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.