Форум на Kuban.ru (http://forums.kuban.ru/)
-   Разработка программ (http://forums.kuban.ru/f1024/)
-   -   Что за фигня с ExecutorService (http://forums.kuban.ru/f1024/chto_za_fignya_s_executorservice-8265264.html)

Добрых дел мастер 02.04.2017 21:11

Что за фигня с ExecutorService
 
Пытаюсь запустить потенциально зависающий код(на Java). Решил запускать его в отдельном потоке, ждать N секунд, если вычисления не завершились - завершаю поток и повторяю. Для эксперимента написал такой код:

boolean isFinished = false;
int step = 0;
while(!isFinished && step < 4) **
Callable<Void> task = ()-> **
for(int i = 0; i<30; i++) **
System.out.println("Hello:"+i);
TimeUnit.SECONDS.sleep(1);
**
return null;
**;
ExecutorService executor = Executors.newSingleThreadExecutor();
ArrayList<Callable<Void>> tasks = new ArrayList<>();
tasks.add(task);
try **
executor.invokeAll(tasks,3, TimeUnit.SECONDS);
** catch (InterruptedException e) **
e.printStackTrace();
**
executor.shutdownNow();
if(executor.isTerminated()) **
System.out.println("!!!!!!!!!!!!!!!!"+step);
** else **
isFinished = true;
**
step++;
**

Этот цикл почему-то выполняется только 2 раза.
Чуть-чуть меняю код, добавляю 2 println.

boolean isFinished = false;
int step = 0;
while(!isFinished && step < 4) **
Callable<Void> task = ()-> **
for(int i = 0; i<30; i++) **
System.out.println("Hello:"+i);
TimeUnit.SECONDS.sleep(1);
**
return null;
**;
ExecutorService executor = Executors.newSingleThreadExecutor();
ArrayList<Callable<Void>> tasks = new ArrayList<>();
tasks.add(task);
try **
executor.invokeAll(tasks,3, TimeUnit.SECONDS);
** catch (InterruptedException e) **
e.printStackTrace();
**
executor.shutdownNow();
System.out.println("executor.isTerminated() = "+executor.isTerminated());
if(executor.isTerminated()) **
System.out.println("!!!!!!!!!!!!!!!!"+step);
** else **
isFinished = true;
**
System.out.println("executor.isTerminated() = "+executor.isTerminated());
step++;
**


Цикл начинает выполняться 4 раза. Но обратите внимание на значение переменной executor.isTerminated(): Такое впечатление, что isTerminated не сразу получает нужное значение, а через неопределенное, пусть и маленькое время.
Что за нафиг?

Добрых дел мастер 02.04.2017 21:22

кстати, вывод, на который стоит обратить внимание:
Hello:0
Hello:1
Hello:2
executor.isTerminated() = true
!!!!!!!!!!!!!!!!0
executor.isTerminated() = true
Hello:0
Hello:1
Hello:2
executor.isTerminated() = false
!!!!!!!!!!!!!!!!1
executor.isTerminated() = true
Hello:0
Hello:1
Hello:2
executor.isTerminated() = false
!!!!!!!!!!!!!!!!2
executor.isTerminated() = true
Hello:0
Hello:1
Hello:2
executor.isTerminated() = false
!!!!!!!!!!!!!!!!3
executor.isTerminated() = true


Кстати, подскажите, как вставлять исходники, чтобы фигурные скобки не превращались в звездочки, а отступы не исчезали?

Добрых дел мастер 02.04.2017 21:31

и, кстати, почему InterruptedException не вызывается?

Добрых дел мастер 02.04.2017 22:07

о, вот так работает:
boolean isFinished = false;
int step = 0;
while(!isFinished && step < 4) **
Callable<Void> task = () -> **
for (int i = 0; i < 30; i++) **
System.out.println("Hello:" + i);
TimeUnit.SECONDS.sleep(1);
**
return null;
**;
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Void> future = executor.submit(task);
try **
future.get(5,TimeUnit.SECONDS);
** catch (TimeoutException e) **
future.cancel(true);
executor.shutdownNow();
e.printStackTrace();
** catch (InterruptedException e) **
e.printStackTrace();
** catch (ExecutionException e) **
e.printStackTrace();
**

executor.shutdownNow();
if (future.isCancelled()) **
System.out.println("!!!!!!!!!!!!!!!!" + step);
** else **
isFinished = true;
**
step++;
**

wayerr 03.04.2017 18:25

Форум расхренячил исходники и ничего не понятно, но скорее всего проблема в том что доступ к shared данным (например счетчикам) надо защищать блокировками

Фантом 03.04.2017 19:06

0-Добрых дел мастер >Привет. Написал тебе на почту (не по этой теме, по другому вопросу)

Добрых дел мастер 04.04.2017 07:56

да, и я не понял, как правильно вставлять исходники. Но насколько я понял, пара звездочек - это фигурная скобка.

Так это внутренности executorService-а, как я там могу что-то защищать?

2Фантом. Так я же ответил. Правда, я пока отвечаю медленно. Я в командировке в солнечном Надыме.

wayerr 04.04.2017 21:45

>, как правильно вставлять исходники

сюда [url]https://pastebin.com/[/url] а ссылку на форум - например


Текущее время: 09:13. Часовой пояс GMT +3.