同步:我的代码出了什么问题?

时间:2014-02-03 10:52:12

标签: java multithreading synchronization

我正在阅读同步here。然后我写了这个程序

public class Counter {

    int i = 0;

    public synchronized void increment() {
        System.out.println("inc called");
        i++;
        System.out.println("inc exited");
    }

    public synchronized void decrement() {
        System.out.println("dec called");
        i--;
        System.out.println("dec exited");
    }

    public synchronized void print(String name) {
        System.out.println(name + " " + i);
    }

}

public class UnsynchronizedCounterTest implements Runnable {

    private Counter counter = new Counter();

    public UnsynchronizedCounterTest(String name) {
        Thread t = new Thread(this, name);
        t.start();
    }

    public static void main(String[] args) {
        UnsynchronizedCounterTest test = new UnsynchronizedCounterTest(
                "New Thread 1");
        test.callMe();
    }

    public void callMe() {
        counter.decrement();
        counter.print("main thread");
    }

    @Override
    public void run() {
        counter.increment();
        counter.print("another thread");
    }
}

当我运行此程序时,我得到低于输出

dec called
dec exited
inc called
inc exited
another thread 0
main thread 0

dec called
dec exited
main thread -1
inc called
inc exited
another thread 0

我认为第一个输出是错误的。我不知道我的程序有什么问题。任何人都可以纠正我。

2 个答案:

答案 0 :(得分:4)

第一个输出是正确的,因为锁是粒度方法调用。

您的输出描述了合理执行的合理执行:

  1. main调用dec(),抓住锁,减量,退出,释放锁;
  2. other来电inc();抓住锁,增量,退出,释放锁;
  3. main来电print();抓住锁,读取0,退出,释放锁;
  4. other调用print(),抓取锁定,读取0,退出,释放锁定。

答案 1 :(得分:3)

以下代码:

    counter.decrement();
    counter.print("main thread");

很危险。虽然它在99%打印正确的Counter.i值,但有时另一个线程可以楔入第一个和第二个方法调用之间的间隙。更好地在减量和增量方法中打印值。如果您只想打印而不更改值,只需使用同步方法或块,以避免打印过时值。

输出对应于您的程序 - 如果您认为它们错了,您的程序也是错误的。请解释一下你想要的东西。