Завершить определённый поток последним
Поток 1: Происходит поиск новостей с выводом в конце Search completed in...
Thread searchThread = new Thread(() -> readRSS());
searchThread.start();
public static void readRSS() {
Window.Searching();
for (i = 0; i < news_sources.length; i++) {
/*много кода*/
}
//Search time
Window.timeend = System.currentTimeMillis();
searchTime = (Window.timeend - Window.timestart) / 1000;
DecimalFormat f = new DecimalFormat("##.00");
Window.lblSearch.setText("Search completed in "+f.format(searchTime)+" s.");
}
Поток 2: Параллельно с поиском сделана "анимация" поиска, путём добавления и убирания точек.
public static void Searching() {
Thread thr = new Thread(() -> {
for (News.i = 0; News.i < News.news_sources.length; ) {
try {
lblSearch.setText("Searching");
Thread.sleep(500);
lblSearch.setText("Searching.");
Thread.sleep(500);
lblSearch.setText("Searching..");
Thread.sleep(500);
lblSearch.setText("Searching.");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thr.start();
}
Всё работает красиво, но иногда после вывода, что поиск завершён, выскакивает поток с "анимацией" и вместо итога стоит "Searching.". Как сделать так, чтобы 2й поток никогда не продолжался после вывода итога первого потока?
Ответы (1 шт):
Прямолинейный вариант: флаг завершения.
Создаем переменную, типа AtomicBoolean. Установим её в false при запуске поиска, и в true при завершении (до вывода результата). Передадим ее в Searching:
public static void readRSS() {
AtomicBoolean isSearchFinished = new AtomicBoolean(false);
Window.Searching(isSearchFinished);
...
isSearchFinished.set(true);
Window.lblSearch.setText("Search completed in " + f.format(searchTime) + " s.");
}
В потоке анимации проверяем флаг и, если поиск завершен, то ничего не делаем:
public static void Searching(AtomicBoolean isSearchFinished) {
...
if(isSearchFinished.get()) return;
lblSearch.setText("Searching");
Thread.sleep(500);
if(isSearchFinished.get()) return;
lblSearch.setText("Searching.");
}
Не проверял, но вроде должно сработать.
Еще варианты:
- Возвращать из
Searchingссылку на поток анимации. Перед выводом результатов прерывать поток (interrupt) и дожидаться завершения (join). - Создать переменную-флаг на уровне класса и синхронизировать к ней доступ.