Java 在相继运行的两个线程之间添加延迟
我试图在两个线程之间留出5秒的间隔,一个接一个地运行,即假设我的第一个线程打印“X”,将有5秒的延迟,然后另一个线程打印“Y”,再次延迟5秒,然后是“X”&这将继续,比如说30次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; }
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来说并不常见将这些类型的循环交给彼此(您可以将其作为具有两个睡眠的单线程循环)。