我正在尝试创建多个线程,这些线程按顺序依次打印数字。
我试图做的是为每个线程分配一个值,并且仅在
时打印 counter % (no of threads) == value of that thread else the thread waits
当我使用2个线程尝试此操作时,我可以实现结果,但是该程序无法正确运行3个线程。
import java.util.*;
import java.lang.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
printer p1 = new printer(l,0);
printer p2 = new printer(l,1);
printer p3 = new printer(l,2);
Thread t1 = new Thread(p1);
Thread t2 = new Thread(p2);
Thread t3 = new Thread(p3);
t1.start();
t2.start();
t3.start();
}
static Object l = new Object();
static int c = 0;
}
class printer implements Runnable{
Object lock;
static int i = 0;
int j;
printer(Object lock,int j){
this.lock = lock;
this.j=j;
}
public void run(){
synchronized(lock){
try{
while(i<1000){
System.out.println(Thread.currentThread().getName()+" starting to check with j="+j+ " i="+i);
if(i%3!=j){
System.out.println(Thread.currentThread().getName()+" not the one so waiting");
lock.wait();
}
System.out.println(Thread.currentThread().getName()+" i="+i);
i++;
lock.notifyAll();
}
}catch(InterruptedException ex ){
}
}
}
}
这是程序的输出:
Thread-0 starting to check with j=0 i=0
Thread-0 i=0
Thread-0 starting to check with j=0 i=1
Thread-0 not the one so waiting
Thread-1 starting to check with j=1 i=1
Thread-1 i=1
Thread-1 starting to check with j=1 i=2
Thread-1 not the one so waiting
Thread-0 i=2
Thread-0 starting to check with j=0 i=3
Thread-0 i=3
Thread-0 starting to check with j=0 i=4
Thread-0 not the one so waiting
Thread-1 i=4
Thread-1 starting to check with j=1 i=5
Thread-1 not the one so waiting
Thread-0 i=5
我不明白的是,Thread-0 i=2
是如何在未经检查的情况下由线程0打印的。(没有用于线程0检查其值的打印语句)
我期望Thread-2从这里开始,但是相反,Thread-0开始运行。而且,Thread-0也没有执行任何检查,而是立即打印出i的值。
我的目标是了解为什么此功能无法按预期运行以及代码为何具有这种功能。
请不要向我提供其他可达到预期效果的代码段。
答案 0 :(得分:1)
我认为这是怎么回事:
一些线程启动后发现不是那个线程,所以它等待:
if(i%3!=j){
System.out.println(Thread.currentThread().getName()+" not the one so waiting");
lock.wait();
}
然后另一个线程找到它,打印并递增,然后创建notifyAll()
个线程。那么上面的那个线程做什么?它一直在执行。
if(i%3!=j){
System.out.println(Thread.currentThread().getName()+" not the one so waiting");
lock.wait();
}
// just keeps going...
System.out.println(Thread.currentThread().getName()+" i="+i);
i++;
程序按顺序执行。一项检查之后,程序唯一可以做的就是移至下一个打印语句。该代码没有其他功能。
检查和等待的标准方法是使用while
循环,这样在检查成功之前,您不会退出while
。
while(i%3!=j){
System.out.println(Thread.currentThread().getName()+" not the one so waiting");
lock.wait();
}
未经测试,请尝试一下。