我正在阅读同步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
我认为第一个输出是错误的。我不知道我的程序有什么问题。任何人都可以纠正我。
答案 0 :(得分:4)
第一个输出是正确的,因为锁是粒度方法调用。
您的输出描述了合理执行的合理执行:
main
调用dec()
,抓住锁,减量,退出,释放锁; other
来电inc()
;抓住锁,增量,退出,释放锁; main
来电print()
;抓住锁,读取0,退出,释放锁; other
调用print()
,抓取锁定,读取0,退出,释放锁定。答案 1 :(得分:3)
以下代码:
counter.decrement();
counter.print("main thread");
很危险。虽然它在99%打印正确的Counter.i
值,但有时另一个线程可以楔入第一个和第二个方法调用之间的间隙。更好地在减量和增量方法中打印值。如果您只想打印而不更改值,只需使用同步方法或块,以避免打印过时值。
输出对应于您的程序 - 如果您认为它们错了,您的程序也是错误的。请解释一下你想要的东西。