Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在相继运行的两个线程之间添加延迟_Java_Multithreading - Fatal编程技术网

Java 在相继运行的两个线程之间添加延迟

Java 在相继运行的两个线程之间添加延迟,java,multithreading,Java,Multithreading,我试图在两个线程之间留出5秒的间隔,一个接一个地运行,即假设我的第一个线程打印“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; }

我试图在两个线程之间留出5秒的间隔,一个接一个地运行,即假设我的第一个线程打印“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();
    }
 }
import java.lang.*;
导入java.util.concurrent.TimeUnit;
类PingPong实现了Runnable
{字符串字;
乒乓球(弦乐){
word=s;
}
公开募捐
{
尝试
{

对于(int i=0;i线程是相互独立的,除非引入某种同步机制。因此,您需要做的第一件事是更改您的乒乓球类,使其具有要同步的内容,每个线程都将在其上等待

让我们把这个对象称为
ball
。你可以在
PingPong
的构造函数中传递它。它可以是你想要的任何对象(甚至只是对象),也可以为它创建你自己的小类

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

synchronized(ball) {
  System.out.println(word);
  Thread.sleep(5000);
}
Thread.sleep(1000);
这样,每个线程将阻塞5秒钟,直到它允许另一个线程“获取”球的监视器并输出它的字

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

一种稍微复杂但更正确的方法是使用第二个
重入锁
。同样,您必须将其与前一个
ball
对象一起通过构造函数。我们将其称为

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

  Thread.sleep(5000);
}
unlock()
位于
finally
块中,以确保如果抛出任何异常,锁不会永远保持锁定状态

System.out
实际上不需要在
try
块内,但这使代码更加优雅,而不是有一个空的
try
sleep()
必须在外部,以确保另一个线程在该线程睡眠时通过第一个锁进入


这确保了如果线程Ping处于休眠状态,线程Pong将获得
,因此它将是下一个进入
已同步
块的线程。当Ping唤醒并退出
已同步
块时,即使在Pong之前同时得到调度,它也将无法继续,因为它无法获得锁,并且等待Pong进入
synchronized
块并输出其单词。

如果两个线程同时独立运行,您希望这两个线程如何相互了解?请格式化您的问题,为什么使用caps?您的尝试在哪里?我所看到的只是一个线程每100msUse打印一个单词的两个实例观察者模式,用于此类任务[…]同一个线程不会再获得监视器。我认为java会解决这个问题,因为第二个线程会等待第一个线程释放监视器,然后如果它被释放,会立即抓住球。如果我错了,请纠正我,我不认为这有任何保证,因为当synchronized块结束。我可能也错了……我会检查。@Lino还没有找到太多信息,除了
synchronized
不能保证任何线程调度的公平性。如果一个线程的优先级恰好高于另一个线程,这会更严重,这可能导致饥饿,而优先级较低的线程t线程几乎没有得到任何CPU时间。我想说的是,最好安全运行,并确保严格处理竞争条件。我添加了另一种方法。无论如何,感谢您的研究,很好的回答顺便说一句。如果可以,我会再次投票:)虽然我不太喜欢使用两种不同的锁定机制,但我想没有其他方法可以解决。嗯,
ReentrantLock
是为这种情况添加的,在这种情况下,不能重叠2个
synchronized
块。公平地说,这个问题有点奇怪,我认为这对h来说并不常见将这些类型的循环交给彼此(您可以将其作为具有两个睡眠的单线程循环)。