我正在实现一个简单的多线程示例,其中线程1每1000ms打印一次PING,线程2每2000ms打印一次PONG。
public class T extends Thread
{
public void run()
{
int i =10;
while(i>0)
{
if(Thread.currentThread().getName().equals("T1"))
{
System.out.println("\nPING");
try {Thread.sleep(1000);}
catch (InterruptedException e) {e.printStackTrace();}
}
else if (Thread.currentThread().getName().equals("T2"))
{
System.out.println("\nPONG");
try {Thread.sleep(2000);}
catch (InterruptedException e) {e.printStackTrace();}
}
i--;
}
}
public static void main(String[] args)
{
Thread t1 = new T();
Thread t2 = new T();
t1.setName("T1");
t2.setName("T2");
t1.start();
t2.start();
}
}但是输出是这样的::
PONG
PING
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PONG
PONG
PONG
PONG
PONG
但是我的预期输出应该是这样的
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG.....应该在代码中进行哪些更改?
发布于 2013-10-17 03:06:01
假设两个线程都在时间0开始,不管出于什么原因(线程调度),PONG都是先启动的。
PONG (now wait 2000) // 0 has elapsed
PING (now wait 1000) // 0 has elapsed
PING (now wait 1000) // 1000 has elapsed
PING (now wait 1000) // 2000 has elapsed
PONG (now wait 2000) // 2000 has elasped
... and so on如果你想先关闭s,再关闭一个PONG,考虑使用一些通知机制(信号量、coutdown锁存器等)。不要依赖sleep()。
发布于 2013-10-17 03:04:58
来自Thread.sleep的文档
使当前执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度程序的精确度和准确性。
如果您希望确保线程打印PING运行两次,然后等待另一个线程打印PONG (在继续之前,它又等待两个PING),则需要使线程彼此同步。参见Object.wait和Object.notify。
编辑:这是一个带有同步的版本(它很混乱,但问题中的原始版本也是如此;P):
public class T extends Thread
{
//Static object to synchronize on... bad practice but this is just an example anyway
static Object synchOnMe = new Object();
public void run()
{
int i = 10;
while(i > 0)
{
if(Thread.currentThread().getName().equals("T1"))
{
System.out.println("PING");
try
{
Thread.sleep(1000);
//Synchronize on every second time (ie. wait for PONG)
if((i + 1) % 2 == 0)
{
synchronized(synchOnMe)
{
synchOnMe.notify();
synchOnMe.wait();
}
}
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
else if(Thread.currentThread().getName().equals("T2"))
{
try
{
//Synchronize every time (ie. wait for PING)
synchronized(synchOnMe)
{
synchOnMe.wait();
System.out.println("PONG");
synchOnMe.notify();
}
Thread.sleep(2000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
i--;
}
//One last notify to release the other thread waiting
synchronized(synchOnMe)
{
synchOnMe.notify();
}
}
public static void main(String[] args)
{
Thread t1 = new T();
Thread t2 = new T();
t1.setName("T1");
t2.setName("T2");
t1.start();
t2.start();
}
}输出:
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG发布于 2013-10-17 03:07:11
https://stackoverflow.com/questions/19411567
复制相似问题