Java 如何确保一个线程先于另一个线程启动?
我有两个线程T1和T2。T2应该在从T1收到消息后开始工作。T1和T2都在main()中启动。T1无法启动T2 这就是我到目前为止所做的:Java 如何确保一个线程先于另一个线程启动?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有两个线程T1和T2。T2应该在从T1收到消息后开始工作。T1和T2都在main()中启动。T1无法启动T2 这就是我到目前为止所做的: T1: //do work1 which should be executed before work2 lock2.notify() T2: lock2.wait(); //do work2 which should be executed after work1 ends 问题是,有时T1在T2之前启动,而T2永远不会
T1:
//do work1 which should be executed before work2
lock2.notify()
T2:
lock2.wait();
//do work2 which should be executed after work1 ends
问题是,有时T1在T2之前启动,而T2永远不会收到T1发送的通知并一直等待
我可以使用任何现有的并发实用程序来实现此信令吗
谢谢。通常,无论何时使用
wait()
和notify()
,都应该有某种机制(例如标记变量)来检查等待是否完成。发件人:
[…]此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
synchronized(obj){
而()
obj.wait();
…//执行适合条件的操作
}
在您的情况下,这意味着如果您实际上不需要等待,就永远不会进入循环
也就是说,您可能需要重新考虑从
main()
启动这两个线程;根据您的描述,不清楚您为什么要这样做。一般来说,无论何时使用wait()
和notify()
,您都应该有某种机制(例如标记变量)来检查您是否已完成等待。发件人:
[…]此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
synchronized(obj){
而()
obj.wait();
…//执行适合条件的操作
}
在您的情况下,这意味着如果您实际上不需要等待,就永远不会进入循环
也就是说,您可能需要重新考虑从
main()
启动这两个线程;根据您的描述,不清楚您为什么要这样做。您应该在t2未发送消息时进行T1等待。添加一个共享变量来表示消息,并在
while
语句中使用它。在
lock2.send()之后;调用
lock2.notify();`在T2中,以通知T1是否等待
T1:
while (lock2.isNotSend()){
lock2.wait();
}
lock2.notify()
//do some work
T2:
// processing that sends the message
lock2.send();
lock2.notify();
lock2.wait();
您应该在t2未发送消息时进行T1等待。
添加一个共享变量来表示消息,并在
while
语句中使用它。在
lock2.send()之后;调用
lock2.notify();`在T2中,以通知T1是否等待
T1:
while (lock2.isNotSend()){
lock2.wait();
}
lock2.notify()
//do some work
T2:
// processing that sends the message
lock2.send();
lock2.notify();
lock2.wait();
这两个线程之间需要一些同步机制。下面是一个示例,我使用了一个
倒计时闩锁
。我定义了一个类SyncedThread
,它获取构造函数中传递的CountDownLatch
在main方法中,我创建了这个类的两个实例。第一个thread1
将运行2秒钟,然后向倒计时闩锁发出信号,然后再进行3秒钟的虚拟睡眠。
第二个实例thread2
将等待倒计时锁存器,然后睡眠5秒以模拟工作
首先调用thread2.start()
方法,然后调用thread1.start()
,延迟为500ms,但通过使用同步,您将在输出中看到实际上thread2
正在等待thread1
public class ThreadStarterTest {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(1);
SyncedThread thread1 = new SyncedThread(latch, "thread 1") {
@Override
public void run() {
try {
System.out.println(getName() + " running");
Thread.sleep(2_000);
latch.countDown();
Thread.sleep(3_000);
System.out.println(getName() + " finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
SyncedThread thread2 = new SyncedThread(latch, "thread 2") {
@Override
public void run() {
try {
latch.await();
System.out.println(getName() + " running");
Thread.sleep(5_000);
System.out.println(getName() + " finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
try {
thread2.start();
Thread.sleep(500);
thread1.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class SyncedThread extends Thread {
private final CountDownLatch latch;
public SyncedThread(final CountDownLatch latch, final String name) {
super(name);
this.latch = latch;
}
}
}
这两个线程之间需要一些同步机制。下面是一个示例,我使用了一个
倒计时闩锁
。我定义了一个类SyncedThread
,它获取构造函数中传递的CountDownLatch
在main方法中,我创建了这个类的两个实例。第一个thread1
将运行2秒钟,然后向倒计时闩锁发出信号,然后再进行3秒钟的虚拟睡眠。
第二个实例thread2
将等待倒计时锁存器,然后睡眠5秒以模拟工作
首先调用thread2.start()
方法,然后调用thread1.start()
,延迟为500ms,但通过使用同步,您将在输出中看到实际上thread2
正在等待thread1
public class ThreadStarterTest {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(1);
SyncedThread thread1 = new SyncedThread(latch, "thread 1") {
@Override
public void run() {
try {
System.out.println(getName() + " running");
Thread.sleep(2_000);
latch.countDown();
Thread.sleep(3_000);
System.out.println(getName() + " finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
SyncedThread thread2 = new SyncedThread(latch, "thread 2") {
@Override
public void run() {
try {
latch.await();
System.out.println(getName() + " running");
Thread.sleep(5_000);
System.out.println(getName() + " finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
try {
thread2.start();
Thread.sleep(500);
thread1.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static class SyncedThread extends Thread {
private final CountDownLatch latch;
public SyncedThread(final CountDownLatch latch, final String name) {
super(name);
this.latch = latch;
}
}
}