class Lock implements Runnable{
int i=0;
public synchronized void run(){
for(i=0;i<10;i++){
if(Thread.currentThread().getName().equals("t1") && i == 5)
{try { this.wait();} catch(InterruptedException ie){}}
System.out.print(Thread.currentThread().getName()+" ");
if(Thread.currentThread().getName().equals("t3") && i == 9)
this.notifyAll();
}
}
}
public class ThreadLock {
public static void main(String[] args){
Lock l = new Lock();
Thread t1 = new Thread(l);
Thread t2 = new Thread(l);
Thread t3 = new Thread(l);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
输出是: t1 t1 t1 t1 t1 t3 t3 t3 t3 t3 t3 t3 t3 t3 t3 t1 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2
调用notifyAll方法后,t1不会全部打印10次。 我跑了很多次但是每次打印t1只打了6次。 为什么t1不打印10次? 请尽快回复
答案 0 :(得分:2)
i
是一个实例变量。它由所有线程共享。它应该是一个局部变量。
当第一个线程被唤醒时,它会重新获取锁定,打印其名称,递增i,并在i < 10
时重新评估。但由于其他线程已将i
设置为10,因此循环停止。
答案 1 :(得分:1)
问题是你在线程之间共享相同的索引i
,所以当线程t3存在且t1被唤醒时,索引i
将是10
并且线程中的for循环t1将退出。
答案 2 :(得分:0)
在启动每个线程后尝试在每个线程上调用.join()以确保每个线程在程序退出之前完成?
答案 3 :(得分:0)
虽然JB Nizet已经给出了正确答案,但您可能想知道为什么这只会影响t1
:
当调用run方法(已同步)时,每个线程都重置i
。
但是当你返回t1的执行时 - 它不会重置i
,因为线程已经启动了for
- 循环。
i | output
0 | t1 (FIRST iteration of t1 -> Setting i=0)
1 | t1
2 | t1
3 | t1
4 | t1
5 | t1
0 | t3 (FIRST iteration of t3 -> Setting i = 0)
1 | t3
2 | t3
3 | t3
4 | t3
5 | t3
6 | t3
7 | t3
8 | t3
9 | t3
0 | t2 (FIRST iteration of t2 -> Setting i = 0)
1 | t2
2 | t2
3 | t2
4 | t2
5 | t2
6 | t2
7 | t2
8 | t2
9 | t2
9 | t1 (t1 restored, but i=9 now. One more output, program done)
注意:这至少是您描述的输出正在发生的事情。我认为也可能是t2在t3之前执行,导致输出不同。