gpt4 book ai didi

java - 如何在另一个线程之前执行一个线程?

转载 作者:行者123 更新时间:2023-12-02 13:06:06 26 4
gpt4 key购买 nike

我有一个小问题要问你。

我有两个线程:

  • HelloThread - 这会打印“hello”五次。
  • GoodbyeThread - 这将打印“Goodbye”五次。

我希望先运行 HelloThread,然后在完成后运行 GoodbyeThread
我已经用信号量解决了这个问题(但是信号量并不是真正的java方式,它更多的是C方式)。

HelloThread.java

    /*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package modifiedthreadhellogoodbye;

import static java.lang.Thread.sleep;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.concurrent.Semaphore;

class HelloThread implements Runnable {

private final Object lock;
//private final Semaphore lock;

public HelloThread(Semaphore lock) {
this.lock = lock;
}

public HelloThread(Object lock) {
this.lock = lock;
}

@Override
public void run() {
int pause;
synchronized (lock) {
for (int i = 0; i < 5; i++) {
System.out.println("Hello!");
pause = (int) (Math.random() * 1000);
try {
sleep(pause);
} catch (InterruptedException ex) {
Logger.getLogger(HelloThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
lock.notifyAll();
System.out.println("Outsite hello");
}
//lock.release();

}
}

再见Thread.java

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package modifiedthreadhellogoodbye;

import static java.lang.Thread.sleep;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

class GoodbyeThread implements Runnable {

int pause;
//private final Semaphore lock;
private final Object lock;

public GoodbyeThread(Semaphore lock) {
this.lock = lock;
}

public GoodbyeThread(Object lock) {
this.lock = lock;
}

@Override
public void run() {
synchronized (lock) {
System.out.println("Inside the synchronized");
try {
lock.wait();
} catch (InterruptedException ex) {
Logger.getLogger(GoodbyeThread.class.getName()).log(Level.SEVERE, null, ex);
}

//lock.acquire();
for (int i = 0; i < 5; i++) {
System.out.println("Goodbye");
pause = (int) (Math.random() * 1000);
try {
sleep(pause);
} catch (InterruptedException ex) {
Logger.getLogger(GoodbyeThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

}

这是我运行线程的类:

public class ModifiedThreadObject {

private final Object lock = new Object();
//private final Semaphore lock = new Semaphore(0);

public ModifiedThreadObject() {
HelloThread hello = new HelloThread(lock);
GoodbyeThread goodbye = new GoodbyeThread(lock);

Thread t1 = new Thread(hello);
Thread t2 = new Thread(goodbye);
t1.start();
t2.start();
}

}

主要思想是 GoodbyeThread 应该 wait() 来自 HelloThread 的信号。
如果首先运行 GoodbyeThread ,则它可以正常工作,但首先运行 HelloThread 我有以下输出:

Hello!
Hello!
Hello!
Hello!
Hello!
Outsite hello
Inside the synchronized

HelloThread 发送 notifyAll(),但没有人在等待,因此“信号”丢失...

有人有想法吗?

最佳答案

首先,我对这里单独线程的使用有疑问。如果您希望一件事接二连三地发生,只需使用单个线程即可。

但是,等待一个线程完成很容易 - 只需使用join:

Thread t1 = new Thread(hello);
Thread t2 = new Thread(goodbye);
t1.start();
t1.join();
t2.start();

这样您就不需要在“hello”或“goodbye”代码中进行任何同步。

如果您想要更复杂的内容,我建议您查看java.util.concurrent包。虽然您可以使用wait()notify(),但使用更高级别的构造通常是更好的主意。例如,对于生产者/消费者场景,您可能很想使用 BlockingQueue而不是自己全部实现。

关于java - 如何在另一个线程之前执行一个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27923429/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com