當用戶按下Enter或其他線程完成其工作時,我需要退出應用程序。我在過去做到了這一點的方法是如下:Java如何等待直到線程退出或用戶按下輸入
// Main
final Worker worker = new Worker();
final Thread workerThread = new Thread(worker::run);
workerThread.start();
try {
System.in.read();
} catch (final IOException e) {
// The worker thread finished executing
}
// Worker::run
public void run() {
...
System.in.close();
}
此之前似乎運作得很好,但最近進行一些重構後破門。現在,在另一個線程中調用System.in.close()時,該線程在本地方法close0
中無限期地在FileInputStream :: close中掛起。任何人都可以解釋爲什麼這種方法調用會無限期地掛起,就好像存在死鎖情況一樣?
我對此有一個變通,這是如下:
// Main.java
private static final Object waitObject = new Object();
private static boolean isRunning = true;
private static void notifyWaitObject() {
synchronized (waitObject) {
isRunning = false;
waitObject.notify();
}
}
public static void main(final String[] args) {
// Create a thread to wait until enter is pressed
final Thread waitThread = new Thread(() -> {
try {
System.in.read();
} catch (final IOException e) {
// Eat the exception
} finally {
notifyWaitObject();
}
}, "User Input Thread");
waitThread.setDaemon(true);
waitThread.start();
// Create a worker thread
final Worker worker = new Worker();
final Thread workerThread = new Thread(() -> worker.run(Main::notifyWaitObject));
workerThread.start();
// Wait until either the worker threads are done, or enter is pressed
synchronized (waitObject) {
if (isRunning) waitObject.wait();
}
}
// Worker.java
public void run(final Runnable exitNotifier) {
...
exitNotifier.run();
}
然而,上述似乎不必要的沉重的東西,這似乎應該是比較簡單的。有誰知道更好的方式來實現這個線程安全的方式?
@Holger我已經更新了這個問題,用我實際上最終實現的代碼替換了我的「名義上的」解決方法代碼。 –