在不同的 类 方法中等待和通知
Wait & Notify among different Classes method
虽然我的实际问题有点不同,但解决以下问题会对我有所帮助。
我用 scenebuilder 构建了一个简单的 javafx 应用程序。我想通过我的应用程序中的 textField 从用户那里获取输入,然后在另一个 class 中打印那个 class 说,class A。我怎样才能在 class A 中创建一个线程,等等直到我的另一个 guicontroller 在从 user 获取价值后通知。我想循环执行此操作。
准确地说,我如何在不同 classes 的线程之间使用等待和通知?
请原谅我的问题。提前谢谢
已编辑:我的实际计划是构建一个聊天信使。我有一个线程,在收到用户的输入后,将转发给收件人。用户将在 textField 中提供输入,该输入将在 guicontroller 中处理。
我希望我的 guiController 通知正在等待发送消息的线程。
我该怎么做?
理论上你可以这样做
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
List<String> messages = new LinkedList<>();
Thread thread = new Thread(() -> {
while (true) {
String message;
synchronized (messages) {
if (messages.isEmpty()) {
// empty message queue -> wait
try {
messages.wait();
} catch (InterruptedException ex) {
// unknown cause of interrupt -> just try reading the messages anew
continue;
}
}
message = messages.remove(0);
}
System.out.println("sending message: " + message);
try {
// simulate delay
Thread.sleep(3000);
} catch (InterruptedException ex) {
}
}
});
thread.setDaemon(true);
thread.start();
textField.setOnAction(evt -> {
synchronized (messages) {
// add new message to queue
messages.add(textField.getText());
// notify thread
messages.notify();
}
textField.clear();
});
Scene scene = new Scene(textField);
primaryStage.setScene(scene);
primaryStage.show();
}
然而,有更简单的方法可以实现此效果:
BlockingQueue
此 class 专为这种情况而设计:消费者在必要时等待生产者。
LinkedBlockingQueue<String> messages = new LinkedBlockingQueue<>();
Thread thread = new Thread(() -> {
while (true) {
String message;
try {
message = messages.take();
} catch (InterruptedException ex) {
continue;
}
System.out.println("sending message: "+message);
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
}
}
});
thread.setDaemon(true);
thread.start();
textField.setOnAction(evt -> {
try {
messages.put(textField.getText());
textField.clear();
} catch (InterruptedException ex) {
}
});
使用 ExecutorService
此 class 仅允许您 post 任务将信息发送到 ExecutorService
,后者负责安排和执行任务。您可以简单地为每条消息提交一项任务。
private ExecutorService executor;
@Override
public void init() throws Exception {
executor = Executors.newSingleThreadExecutor();
}
@Override
public void stop() throws Exception {
executor.shutdownNow();
// TODO: handle unsent messages or replace with executor.shutdown()
}
private void postMessage(String message) {
executor.submit(() -> {
System.out.println("sending message: "+message);
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
}
});
}
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
textField.setOnAction(evt -> {
postMessage(textField.getText());
textField.clear();
});
Scene scene = new Scene(textField);
primaryStage.setScene(scene);
primaryStage.show();
}
请注意,有不同的执行程序可用于调整调度和使用多线程。
虽然我的实际问题有点不同,但解决以下问题会对我有所帮助。 我用 scenebuilder 构建了一个简单的 javafx 应用程序。我想通过我的应用程序中的 textField 从用户那里获取输入,然后在另一个 class 中打印那个 class 说,class A。我怎样才能在 class A 中创建一个线程,等等直到我的另一个 guicontroller 在从 user 获取价值后通知。我想循环执行此操作。
准确地说,我如何在不同 classes 的线程之间使用等待和通知?
请原谅我的问题。提前谢谢
已编辑:我的实际计划是构建一个聊天信使。我有一个线程,在收到用户的输入后,将转发给收件人。用户将在 textField 中提供输入,该输入将在 guicontroller 中处理。
我希望我的 guiController 通知正在等待发送消息的线程。
我该怎么做?
理论上你可以这样做
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
List<String> messages = new LinkedList<>();
Thread thread = new Thread(() -> {
while (true) {
String message;
synchronized (messages) {
if (messages.isEmpty()) {
// empty message queue -> wait
try {
messages.wait();
} catch (InterruptedException ex) {
// unknown cause of interrupt -> just try reading the messages anew
continue;
}
}
message = messages.remove(0);
}
System.out.println("sending message: " + message);
try {
// simulate delay
Thread.sleep(3000);
} catch (InterruptedException ex) {
}
}
});
thread.setDaemon(true);
thread.start();
textField.setOnAction(evt -> {
synchronized (messages) {
// add new message to queue
messages.add(textField.getText());
// notify thread
messages.notify();
}
textField.clear();
});
Scene scene = new Scene(textField);
primaryStage.setScene(scene);
primaryStage.show();
}
然而,有更简单的方法可以实现此效果:
BlockingQueue
此 class 专为这种情况而设计:消费者在必要时等待生产者。
LinkedBlockingQueue<String> messages = new LinkedBlockingQueue<>();
Thread thread = new Thread(() -> {
while (true) {
String message;
try {
message = messages.take();
} catch (InterruptedException ex) {
continue;
}
System.out.println("sending message: "+message);
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
}
}
});
thread.setDaemon(true);
thread.start();
textField.setOnAction(evt -> {
try {
messages.put(textField.getText());
textField.clear();
} catch (InterruptedException ex) {
}
});
使用 ExecutorService
此 class 仅允许您 post 任务将信息发送到 ExecutorService
,后者负责安排和执行任务。您可以简单地为每条消息提交一项任务。
private ExecutorService executor;
@Override
public void init() throws Exception {
executor = Executors.newSingleThreadExecutor();
}
@Override
public void stop() throws Exception {
executor.shutdownNow();
// TODO: handle unsent messages or replace with executor.shutdown()
}
private void postMessage(String message) {
executor.submit(() -> {
System.out.println("sending message: "+message);
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
}
});
}
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
textField.setOnAction(evt -> {
postMessage(textField.getText());
textField.clear();
});
Scene scene = new Scene(textField);
primaryStage.setScene(scene);
primaryStage.show();
}
请注意,有不同的执行程序可用于调整调度和使用多线程。