gpt4 book ai didi

java - 如何在新线程中进行此搜索

转载 作者:行者123 更新时间:2023-11-30 04:05:58 24 4
gpt4 key购买 nike

我有输入时搜索功能,尽管它搜索速度非常快,即使没有多线程我也无法注意到它,我仍然想知道如何在此使用多线程

search.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
manager.searchString(s2);
listView.getItems().setAll(manager.getList());
}
});

所以基本上有一个 TextField ,当它的文本发生更改时,我会调用对象 manager 中的搜索方法,该方法在完成时将其搜索结果放入数组中.

然后,ListView 应该在完成时将其数据更新到这个新数组。

如何在一个线程上进行搜索并在完成后更新列表数据?!

我相信我不能只从其他线程调用列表函数,因为 GUI 的东西应该只从一个线程调用。

最佳答案

要在不同的线程中有效地完成此操作并不像听起来那么简单。

您不想在每次按下键时创建并执行一个新线程,因为:

  1. 线程创建会产生系统开销,这将使其成为一个极其密集的过程
  2. 无法保证线程将按照创建的顺序执行和完成,因此您可能会得到较早的线程后一个线程完成,并因此用无效条目更新列表。

您可以使用单线程执行器服务(它使一个线程保持 Activity 状态并使用它来执行按顺序传递给它的 Runnables),这会更有效,但是您需要记住在您的文本字段被破坏(如果您确实破坏了文本字段)。大致如下:

// first of all, at the class level (assuming listView and manager are both class-level variables, preferably final ones, too):

// An INNER class implementing Runnable which will carry out the searching
private class Searcher implements Runnable {
private volatile boolean cancelled = false;
private final String searchTerm;
Searcher(String searchTerm) {
this.searchTerm = searchTerm;
}

public void cancel() {
cancelled = true;
}

@Override
public void run() {
// remember that there's no guarantee that this will execute before the NEXT keypress, so we add a check to ensure that we still want to perform the search when it gets executed:
if (!cancelled) {
manager.searchString(searchTerm);
Platform.runLater(listViewUpdater); // listViewUpdater is defined below
}
}
}

// a Runnable to actually update the GUI after a seach has been performed
private Runnable listViewUpdater = new Runnable(){
@Override
public void run() {
listView.getItems().setAll(manager.getList());
}
}

private ExecutorService executor = Executors.newSingleThreadExecutor();
private Searcher lastSearcher = null;

// ... then, in the method which sets up the GUI
search.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
if (lastSearcher != null) {
lastSearcher.cancel(); // prevents lastSearcher from running if it hasn't done so already
}
lastSearcher = new Searcher(s2);
executor.submit(lastSearcher);
}
});

缺点是每次值更改时都会创建一个新对象,但这并不像每次都创建一个新线程那么糟糕。

关于java - 如何在新线程中进行此搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20712068/

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