为什么n
有时等于1或2
private static int n = 0;
private static Thread t1, t2;
private synchronized static void increment() {
n++;
}
public static void main(String[] args) {
t1 = new Thread(new Runnable() {
public void run() {
increment();
}
});
t2 = new Thread(new Runnable() {
public void run() {
t1.start();
increment();
}
});
t2.start();
try {
t2.join();
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(n);
}
增量方法是否只允许一个线程在任何给定时刻执行它?
也许它是调试器,似乎当我正常运行它时我总是得到2但是当我调试代码时它有时会返回1.
答案 0 :(得分:8)
确实如此,但它可能以任何顺序发生。您只需等待t2
完成,但不能等待t1
完成。
等待t1
。
答案 1 :(得分:3)
private static int n = 0;
private static Thread t1, t2;
private synchronized static void increment() { // Lock will be on the "class" Object
n++;
}
public static void main(String[] args) {
t1 = new Thread(new Runnable() {
public void run() {
increment();
}
});
t2 = new Thread(new Runnable() {
public void run() {
t1.start();
// t1 starts after t2. Now, t1's increment might also be called or t2's increment() might also be called. If t2 calls increment(), then the join() method below (you are joining the in the main thread) will be completed and "n" will be printed (if t1 is not getting appropriate time of execution..)
increment();
}
});
t2.start(); // t2 starts first
try {
t2.join();
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(n); // increment() might not have been called by t1
}
无法保证一个线程会在另一个线程之前执行(即使是同步条件..)。因此,您可以在t1和t2上join
。这将确保您始终以2输出。
答案 2 :(得分:1)
我想如果increment
run
方法中的t2
调用发生在increment
t1
方法t1
之前run
} n
方法,然后t2
被锁定,到时间t1
结束时,n
可能仍在运行,但您正在打印t2
在t1
的增量结束之前递增t2
。
澄清:
t2
开始t1
产生t2
increment
在t1
有机会n
t2
在increment
的{{1}} Thread
在t2
有机会t1
之前加入increment
Thread
在n
有机会t1
之前打印increment