2013-09-21 114 views
0

關於Java同步,我嘗試了一個例子(來自TLF-SOFT-VTC.java.6CFE),但事實證明是錯誤的,爲什麼它不同步?代碼:爲什麼不同步?

public class InterferenceFix extends Thread { 
    String name; 
    static boolean isZero = true; 
    static int counter = 0; 

    public static void main(String arg[]) { 
     InterferenceFix one = new InterferenceFix("one"); 
     InterferenceFix two = new InterferenceFix("two"); 
     one.start(); 
     two.start(); 
    } 

    InterferenceFix(String nameString) { 
     name = nameString; 
    } 

    public void run() { 
     for (int i = 0; i < 100000; i++) { 
      update(); 
     } 
     System.out.println(name + ": " + counter); 
    } 

    synchronized void update() { 
     if (isZero) { 
      isZero = false; 
      counter++; 
     } else { 
      isZero = true; 
      counter--; 
     } 
    } 
} 
+0

一定要用'@ Override'註釋標記'run()'。 –

+2

另外:每天使用牙線,並在穿過街道前查看兩條路線。 –

回答

5

只有你update方法是同步的,這意味着環可以在兩個線程同時運行,只有update本身不能。

而且 - 在​​關鍵字實際鎖定對象this上和你的情況,我們在談論2不同的情況下,這意味着他們鎖在不同的this。這意味着主動 - 線程不會以任何方式干擾彼此的工作,並且它們可以同時運行。

如果這是真的,你想要什麼,你很可能得到更好的創建靜態鎖:

private static final Object lock = new lock(); 

,並更改update(或運行)這樣:

void update() { 
    synchronized (lock) { 
     if (isZero) { 
      isZero = false; 
      counter++; 
     } else { 
      isZero = true; 
      counter--; 
     } 
    } 
} 

如果您需要同步for循環,只需在循環中以相同的方式使用鎖定,而不是在update之內。

+1

'update()'也可以在兩個線程上同時運行;當兩個線程在不同的對象上進行同步時,絕對沒有什麼能夠阻止它們。 –

+0

@MarkPeters正確 - 感謝您的更正:) – Avi

+0

謝謝大家,根據您所說的,我在方法update()之前添加了一個'static',它可以工作。 – user2803064

4

​​對於一個實例方法只是在每個實例上序列化調用​​對於每個類都會這樣做,因此對於所有的調用都是如此。所以他們有不同的鎖定對象。現在可以猜測,可以使用static synchronized方法來修改這些靜態字段。