在两个接一个的线程之间增加延迟

时间:2019-04-02 11:10:32

标签: java multithreading

我正尝试在2个螺距之间插入一个5秒钟的间隙,然后在另一个IE上输入我的第一螺距“ X”,则将延迟5秒钟,然后将另一个螺距打印为“ Y”,再次为5秒延迟,然后显示“ X”,表示已进行了30次。

import java.lang.*;
import java.util.concurrent.TimeUnit;
class PingPong implements Runnable
{   String word;
    PingPong(String s){
     word = s;
    }

    public void run()
    {

    try

    {

         for(int  i = 0; i<30; i++)

          {
              System.out.println(word);
              Thread.sleep(100) ;
           }
    } catch (InterruptedException e)

     { e.printStackTrace(); }

   }
   public static void main(String[] args){

     Runnable p1 =  new PingPong("ping");

     Thread  t1 = new Thread(p1);

     t1.start();
     Runnable p2 = new PingPong("pong");

     Thread t2 = new Thread(p2);
     t2.start();
    }
 }

1 个答案:

答案 0 :(得分:1)

除非引入某种同步机制,否则线程彼此独立。因此,您需要做的第一件事就是更改PingPong类以使其同步,每个线程都将在该同步上等待。

我们将此对象称为ball。您可以在PingPong的构造函数中传递它。它可以是任何您想要的对象(甚至只是对象),也可以为其创建自己的小型类。

然后在循环中,您可以执行以下操作:

synchronized(ball) {
  System.out.println(word);
  Thread.sleep(5000);
}
Thread.sleep(1000);

这样,每个线程将阻塞5秒钟,直到允许另一个线程“拿起”球的监视器并输出其文字为止。

第二次睡眠是任意的,但很重要,因此同一线程不会再次获得监视器。

一种稍微复杂但更正确的方法是使用第二个ReentrantLock。同样,您必须将其与上一个ball对象一起传递给构造函数。我们称之为lock

lock.lock();
synchronized(ball) {
  try {
    System.out.println(word);
  } finally {
    lock.unlock();
  }

  Thread.sleep(5000);
}

unlock()位于finally块中,以确保如果引发任何异常,则锁定不会永远保持锁定状态。

System.out实际上并不需要放在try块中,但这使代码更加优雅,而不是空的trysleep()必须在外面,以确保另一个线程在该线程处于休眠状态时通过第一个锁进入。

这可确保如果线程 Ping 处于睡眠状态,则线程 Pong 将占用lock,因此它将紧邻synchronized内。块。当 Ping 醒来并退出synchronized块时,即使巧合地在 Pong 之前安排了时间,它也无法继续执行,因为它可以t取下锁,必须等待 Pong 进入synchronized块中并输出其字。