我正在创建一个扫描收件箱的JavaFX .
有2个按钮,一个用于开始扫描,另一个用于暂停扫描 .
为了实现这一点,我创建了一个新线程,在一个runnable中传递它,调用scanInbox()函数 .
但是,当我按下暂停按钮来调用thread.wait()时,它似乎卡住了 .
在这里实现此功能的最佳方法是什么?
public class WebsiteOverviewController {
@FXML
private TableView<Website> deleteTable;
@FXML
private TableColumn<Website, String> deleteColumn;
@FXML
private TableView<Website> keepTable;
@FXML
private TableColumn<Website, String> keepColumn;
@FXML
private JFXButton scanButton;
@FXML
private JFXButton pauseButton;
private BooleanProperty isScanning = new SimpleBooleanProperty(false);
private MainApp mainApp;
private FilteredList<Website> keepData;
private FilteredList<Website> deleteData;
Task<Void> task;
Thread thread;
public WebsiteOverviewController() {
}
@FXML
public void initialize() {
deleteColumn.setCellValueFactory(cellData -> cellData.getValue().websiteProperty());
keepColumn.setCellValueFactory(cellData -> cellData.getValue().websiteProperty());
scanButton.visibleProperty().bind(isScanning.not());
pauseButton.visibleProperty().bind(isScanning);
}
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
keepData = new FilteredList<>(mainApp.getWebsiteData(), p -> p.getKeep());
deleteData = new FilteredList<>(mainApp.getWebsiteData(), p -> !p.getKeep());
deleteTable.setItems(deleteData);
keepTable.setItems(keepData);
}
@FXML
public void handleScanInbox() {
isScanning.set(true);
thread = new Thread(new Runnable() {
@Override
public void run() {
mainApp.handleScanInbox();
}
});
thread.start();
}
@FXML
public void handlePauseScanInbox() {
isScanning.set(false);
try {
synchronized(thread) {
thread.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2 回答
您可以使用AtomicBoolean实现它,在暂停时将其设置为true,并在mainApp.handleScanInbox()方法中检查它 . 根据您的要求,您可以检查它是否暂停每次迭代,每10次迭代或每次运行该方法
Alex的解决方案工作正常,但如果您仍想使用较低级别的线程管理(wait-notify),那么您可以这样做:
更新
如果您希望能够调用特定以在暂停和恢复之间切换,则可以为此添加另一种方法:
无论如何,你应该尽量避免这种情况:
这是因为
MainApp.paused
可能会在getter和pause()
(即竞争条件)之间发生变化 .更新2
如果您只想使用单个方法来启动/恢复该线程,则只需创建该线程(如果它是
null
),否则调用resume()
.我已将
if (paused.get())
更改为while (paused.get())
,以防notify()
被意外调用paused
.