如何在java中设置线程的计时?
我正在实现一个简单的多线程示例,其中线程1每1000毫秒打印一次PING,线程2每2000毫秒打印一次PONG如何在java中设置线程的计时?,java,multithreading,Java,Multithreading,我正在实现一个简单的多线程示例,其中线程1每1000毫秒打印一次PING,线程2每2000毫秒打印一次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 {Thr
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();
}
}
但输出如下所示:
庞
平
平
平
庞
平
平
庞
平
平
庞
平
平
庞
平
庞
庞
庞
庞
庞
但是我的预期输出应该是
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG.....
应在代码中进行哪些更改?来自以下文档:
导致当前正在执行的线程休眠(暂时停止
执行)指定的毫秒数,取决于
系统计时器和调度程序的精度和准确性。
如果要确保线程打印PING运行两次,然后等待另一个线程打印PONG(而它在继续之前又等待两次PING),则需要使线程彼此同步。见和
编辑:这里有一个同步版本(虽然很混乱,但问题中的原始版本也是如此;p):
输出:
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
根据以下文件:
导致当前正在执行的线程休眠(暂时停止
执行)指定的毫秒数,取决于
系统计时器和调度程序的精度和准确性。
如果要确保线程打印PING运行两次,然后等待另一个线程打印PONG(而它在继续之前又等待两次PING),则需要使线程彼此同步。见和
编辑:这里有一个同步版本(虽然很混乱,但问题中的原始版本也是如此;p):
输出:
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
假设两个线程都在时间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
如果您想<代码> ping <代码> s,然后一个<代码> p>代码>,请考虑使用一些通知机制(信号量、Cut羽绒锁存器等)。不要依赖于
sleep()
假设两个线程都在时间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
如果您想<代码> ping <代码> s,然后一个<代码> p>代码>,请考虑使用一些通知机制(信号量、Cut羽绒锁存器等)。不要依赖于
sleep()
我会使用新并发包中的线程池:
我将使用新并发包中的线程池: 移动
System.out.println("\nPING or PONG");
在线程.sleep()之后,而不是之前
或者在启动踏板时在踏板之间添加Thread.sleep()
t1.start();
Thread.sleep(100);
t2.start();
(但我不喜欢第二种解决方案)
尽管这不是一个专业的解决方案,但它应该可以工作大约30次迭代。
稍后,由于它们没有正确同步,因此不再工作。移动
System.out.println("\nPING or PONG");
在线程.sleep()之后,而不是之前
或者在启动踏板时在踏板之间添加Thread.sleep()
t1.start();
Thread.sleep(100);
t2.start();
(但我不喜欢第二种解决方案)
尽管这不是一个专业的解决方案,但它应该可以工作大约30次迭代。
稍后,由于它们没有正确同步,因此不再工作。首先,应该使用for循环而不是while循环。这让你的意图更加清晰。其次,您需要了解线程不能保证按照启动顺序执行。可以保证的是,内核将根据底层操作系统的工作方式开始为线程分配时间片,并且内核将至少等待您指定的线程睡眠时间(如果内核支持联合线程,有时甚至更少)
这意味着T1实际上可以在一轮中等待996毫秒,T2可以在另一轮中等待2026毫秒。例如,当我运行这段代码时,我得到了以下输出:
PING
庞
PING
PING
庞
PING
PING
庞
PING
庞
PING
PING
庞
PING
PING
庞
庞
庞
庞
庞
有点乱。现在,在许多多线程应用程序中,当线程彼此不依赖时,这是正常的。但是,如果希望输出按照预期的方式排列,那么就像其他答案所建议的那样,需要使用wait()和notify()
例如,先让T1开始,然后让T1开始T2。T2应该在执行时立即等待,然后T1应该在每次ping时通知T2。T2然后可以计算它收到通知的次数,每当计数为偶数时,它就可以输出一个PONG
我将实现作为练习保持打开状态。首先,应该使用for循环而不是while循环。这让你的意图更加清晰。其次,您需要了解线程不能保证按照启动顺序执行。可以保证的是,内核将根据底层操作系统的工作方式开始为线程分配时间片,并且内核将至少等待您指定的线程睡眠时间(如果内核支持联合线程,有时甚至更少)
这意味着T1实际上可以在一轮中等待996毫秒,T2可以在另一轮中等待2026毫秒。例如,当我运行这段代码时,我得到了以下输出:
PING
庞
PING
PING
庞
PING
PING
庞
PING
庞
PING
PING
庞
PING
PING
庞
庞
庞
庞
庞
有点乱。现在,在许多多线程应用程序中,当线程彼此不依赖时,这是正常的。但是,如果希望输出按照预期的方式排列,那么就像其他答案所建议的那样,需要使用wait()和notify()
例如,先让T1开始,然后让T1开始T2。T2应在执行时立即等待