Java 如何确保一个线程先于另一个线程启动?

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和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发送的通知并一直等待

我可以使用任何现有的并发实用程序来实现此信令吗


谢谢。

通常,无论何时使用
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;
        }
    }

}