我有一个小问题要问你。
我有两个线程:
HelloThread
-这将打印“hello”五次。 GoodbyeThread
-这将打印“再见”五次。 我希望先运行
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();
}
}
GoodbyeThread.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);
}
}
}
}
}
这是我的类(class)执行绪的人:
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”或“再见”代码内进行任何同步。
如果您想要更复杂的内容,建议您查看
java.util.concurrent
包。虽然可以使用wait()
和notify()
,但是通常最好使用更高级别的构造。例如,对于生产者/消费者方案,您可能要使用 BlockingQueue
而不是自己全部实现。