Задать вопрос
VasG
@VasG

Как в Java узнать о том, что поток (thread) закончил выполняться?

Я только вчера начал использовать эти потоки, и ещё «не в теме».

Хочется организовать пакетную обработку изображений, и для этого было сделано два потока: thrProcess и thrUpdateUI, соответственно для выполнения обработки изображений и обновления интерфейса (добавление уменьшенных копий результата). Причём второй запускается из первого (просто в конце написано thrUpdateUI.start())


Есть массив, в котором хранятся абсолютные пути до изображений: imgToProcPath[].


Собственно и всё, выше описаны потоки, и я пытаюсь их запустить:

for (int i = 0; i < imgToProcPath.length; i++) {

    thrProcess.start();
}



(если так делать ни в коем случае нельзя — большая просьба не точить на меня вилы сразу)


Но почему-то вызывается только один поток (нулевой).

Может быть есть способ дождаться, пока оба потока завершатся и тогда уже приступать к следующей итерации? Но как?
  • Вопрос задан
  • 8278 просмотров
Подписаться 2 Оценить 1 комментарий
Решения вопроса 1
sainnr
@sainnr
Насколько я понимаю, у вас немного неверное представление о потоках. В коде, приведенном вами, одному и тому же потоку thrProcess дается команда запуска при каждой итерации. Зачем его запускать несколько раз, если он уже выполнил start() после первой итерации (при i = 0)?

В таком случае, вы можете:
1) перенести цикл, проходящий по всем изображениям массива, внутрь рабочего метода потока thrProcess и запустить данный поток один раз;
2) создавать в цикле на каждой итерации новый поток (thrProcess1, thrProcess2, ..., thrProcessN), в котором будет проводиться обработка текущего изображения, и запускать его.

Второй вариант весьма странный — согласитесь, если у вас 1000 изображений, то создавать по 1 потоку для каждого из них, т.е. 1000 потоков всего, будет как-то не хорошо.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
romik
@romik
Один объект Thread — один поток, даже если вы вызовете start несколько раз. В вашем случае разумно воспользоваться более высокоуровневой абстракцией типа ExecutorService.

ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<MyResult>> futures = new ArrayList<>();
for (File path: imgToProcPath) {
    executor.submit(new MyImageProcessingTask(path);
}
for (Future<MyResult> future: futures) {
   displayThumbnail(future.get());
}
Ответ написан
antoo
@antoo
for (int i = 0; i < 10; i++)
            {
                
                Thread thread = new Thread(new ThreadStart(ФУНКЦИЯ ВЫПОЛНЯЮЩАЯСЯ В ПОТОКЕ));
                thread.Name = Convert.ToString(i);
                thread.Start();
            }


И не забудь проверить imgToProcPath.length;
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы