为什么不同步?

时间:2013-09-21 22:49:49

标签: java synchronized

关于Java synchronized,我尝试了一个例子(来自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--;
        }
    }
}

2 个答案:

答案 0 :(得分:5)

只有你的update方法同步,这意味着循环可以在两个线程上同时运行,只有update本身不能。

此外 - synchronized关键字实际上锁定了对象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 :(得分:4)

实例方法上的

synchronized只是序列化每个实例的调用,静态方法上的synchronized会对每个类执行此操作,因此对所有调用都是如此。所以他们有不同的锁定对象。现在可以猜到,可以使用static synchronized方法修改这些静态字段。