java并发问题
为什么java并发问题,java,concurrency,Java,Concurrency,为什么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() { inc
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。是的,但它可能以任意顺序发生。您只等待
t2
完成,而不等待t1
完成
同时等待t1
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的形式获得输出。我想如果t2
的run
方法中的increment
调用发生在t1
的run
方法中调用increment
方法之前,然后,n
被锁定,在t2
结束时,t1
可能仍在运行,但在t1
的增量结束之前,您正在打印出n
增量为t2
澄清:
开始t2
生成t2
t1
在t2
有机会t1
在n
的t2
增量期间被锁定
- 主
在线程
之前加入t1
有机会t2
增量
- main
在Thread
有机会t1
递增之前打印
n
t1.start()在t2
run方法中的code>。@ElliottFrisch-静态线程实例会有什么影响?。即使线程实例不是静态的,他仍然会以同样不可预测的行为结束。对吗?@最重要的是,不仅仅是静态线程实例,我观察到所有的东西都是静态的。还有,为什么会有呢?这就是为什么不在main
方法中声明它们呢?@ElliottFrisch-Oh。。好的……)