gpt4 book ai didi

java - 任务取消方法或事件

转载 作者:行者123 更新时间:2023-12-02 11:45:17 25 4
gpt4 key购买 nike

我正在尝试创建一个网络javafx应用程序并在任务中运行serverloop。因为 ServerSocket 的接受方法是阻塞的,所以我无法测试任务是否被取消(使用 isCancelled())。

我当前的实现:

class ServerTask extends Task<Void> {
ExecutorService executorService;
final int PORT = 12345;

@Override
protected Void call() throws Exception {
executorService = Executors.newFixedThreadPool(8);

try (ServerSocket serverSocket = new ServerSocket(PORT)) {
while (true)
{
executorService.execute(
new Client(serverSocket.accept()));
}
}
catch (IOException e) {
System.out.print(e.getMessage());
}

return null;
}
}

当任务中调用chancel时,是否有可能覆盖或捕获事件,或者我在javafx应用程序中实现serverloop的方法是否错误?如果可以的话应该怎么做?

最佳答案

一旦调用 cancel()Task 就会转换为 CANCELLED 状态,即使 call() 方法仍然被阻止运行不可中断的方法。

通过关闭套接字,可以有效地“中断”ServerSocket,这将导致当前被阻止的任何 accept() 方法终止并出现 IOException .

所以你可以这样做:

class ServerTask extends Task<Void> {
ExecutorService executorService;
final int PORT = 12345;

private ServerSocket serverSocket ;

@Override
protected Void call() throws Exception {
executorService = Executors.newFixedThreadPool(8);

try (serverSocket = new ServerSocket(PORT)) {
while (true)
{
executorService.execute(
new Client(serverSocket.accept()));
}
}
catch (IOException e) {
if (isCancelled()) {
System.out.println("Cancelled");
} else {
System.out.print(e.getMessage());
}
}

return null;
}

@Override
protected void cancelled() {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException exc) {
exc.printStackTrace();
}
}
}
}

这是一个非常快速的完整示例:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class NonIterruptableTaskCancellation extends Application {

@Override
public void start(Stage primaryStage) throws Exception {

ServerSocket socket = new ServerSocket(2048);

Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {

while (! isCancelled()) {
try {
Socket s = socket.accept();
System.out.println("Connected to "+s);
s.close();
} catch (IOException exc) {
if (isCancelled()) {
System.out.println("Cancelled");
} else {
System.out.println("Unexpected IO Exception");
throw exc ;
}
}
}

return null ;
}

@Override
protected void cancelled() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};

Thread t = new Thread(task);
t.setDaemon(true);
t.start();

Label label = new Label();
label.textProperty().bind(task.stateProperty().asString());

Button cancel = new Button("Cancel");
cancel.disableProperty().bind(task.runningProperty().not());
cancel.setOnAction(e -> task.cancel());

VBox root = new VBox(5, label, cancel);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);

Scene scene = new Scene(root, 200, 120);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}
}

关于java - 任务取消方法或事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48254076/

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