首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在java中设置线程的计时?

问如何在java中设置线程的计时?
EN

Stack Overflow用户
提问于 2013-10-17 02:59:22
回答 6查看 1.6K关注 0票数 1

我正在实现一个简单的多线程示例,其中线程1每1000ms打印一次PING,线程2每2000ms打印一次PONG。

代码语言:javascript
复制
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

但是我的预期输出应该是这样的

代码语言:javascript
复制
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG.....

应该在代码中进行哪些更改?

EN

回答 6

Stack Overflow用户

发布于 2013-10-17 03:06:01

假设两个线程都在时间0开始,不管出于什么原因(线程调度),PONG都是先启动的。

代码语言:javascript
复制
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()。

票数 4
EN

Stack Overflow用户

发布于 2013-10-17 03:04:58

来自Thread.sleep的文档

使当前执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度程序的精确度和准确性。

如果您希望确保线程打印PING运行两次,然后等待另一个线程打印PONG (在继续之前,它又等待两个PING),则需要使线程彼此同步。参见Object.wait和Object.notify。

编辑:这是一个带有同步的版本(它很混乱,但问题中的原始版本也是如此;P):

代码语言:javascript
复制
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();
    }
}

输出:

代码语言:javascript
复制
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
PING
PING
PONG
票数 2
EN

Stack Overflow用户

发布于 2013-10-17 03:07:11

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19411567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档