Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Progress and completition indication [JCIP 9.7/9.8] / 8 сообщений из 8, страница 1 из 1
01.03.2017, 19:22
    #39412774
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
Написали вот такую абстрактную таску, которая поддерживает колбэк на завершение самой себя, cancel и просмотр прогресса

http://www.periodicooficial.oaxaca.gob.mx/files/2011/05/EXT02-2011-05-19.pdf Background Task Class Supporting Cancellation, Completion Notification, and Progress Notification :

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
 abstract class BackgroundTask<V> implements Runnable, Future<V> {
        private final FutureTask<V> computation = new Computation();
        private class Computation extends FutureTask<V> {
            public Computation() {
                super(new Callable<V>() {
                    public V call() throws Exception {
                        return BackgroundTask.this.compute() ;
                    }
                });
            }
            protected final void done() {
                GuiExecutor.instance().execute(new Runnable() {
                    public void run() {
                        V value = null;
                        Throwable thrown = null;
                        boolean cancelled = false;
                        try {
                            value = get();
                        } catch (ExecutionException e) {
                            thrown = e.getCause();
                        } catch (CancellationException e) {
                            cancelled = true;
                        } catch (InterruptedException consumed) {
                        } finally {
                            onCompletion(value, thrown, cancelled);
                        }
                    };
                });
            }
        }
        protected void setProgress(final int current, final int max) {
            GuiExecutor.instance().execute(new Runnable() {
                public void run() { onProgress(current, max); }
            });
        }
        // Called in the background thread так как задача длинная и мы хотим, чтобы приложение не подвисало.
        protected abstract V compute() throws Exception;
        // Called in the event thread - почему?
        protected void onCompletion(V result, Throwable exception,
                                    boolean cancelled) { }
        protected void onProgress(int current, int max) { }
        // Other Future methods forwarded to computation
        //вызываем этот метод, если хотим сделать cancel задаче. Вызывается в event thread насколько я понимаю
        public boolean cancel(boolean mayInterruptIfRunning) { 
             return computation.cancel(mayInterruptIfRunning);
        }
        public void run() {// просто делегируем объекту computation 
             computation.run();
        }
    }



вот не понимаю почему onCompletion вызывается в eventThread, а задача в другом треде.

Чтобы проверить написал пример:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
       FutureTask futureTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                System.out.println(Thread.currentThread().getId() + " works");

                return null;
            }

        }) {
            @Override
            protected void done() {
                System.out.println(Thread.currentThread().getId() + " done");
            }
        };

        ExecutorService executorService = Executors.newFixedThreadPool(1);
        executorService.execute(futureTask);
        executorService.shutdown();




Так вот тут вывод:
Код: java
1.
2.
11 works
11 done



Тут done вызывается в том же потоке, что и задача.

В чем разница с примером из книги?
...
Рейтинг: 0 / 0
01.03.2017, 21:45
    #39412841
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
Наверное не так вопрос задаю. В принципе не понятно, что этот код делает.

Да, понятна общая концепция, что длинные задачи, чтобы не тормозил ui, следует выполнять в отдельн(-ом/-ых) потоке, но как-то по обрывкам кода не понял я его.
...
Рейтинг: 0 / 0
01.03.2017, 23:10
    #39412867
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
questionerНаверное не так вопрос задаю. В принципе не понятно, что этот код делает.

Да, понятна общая концепция, что длинные задачи, чтобы не тормозил ui, следует выполнять в отдельн(-ом/-ых) потоке, но как-то по обрывкам кода не понял я его.
тогда делают так:
- делают цикл из млн. элементов чтобы тормозищ ГУИ (нет реакции на закрыть окно)
- исправляют данный кейс и тестируют.
Логично?
Теория без практики мертва.
...
Рейтинг: 0 / 0
02.03.2017, 10:31
    #39412978
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
Petro123,

ммм...да, очевидно верно, но вопрос в другом) непонятно исполнение и использование приведенного кода
...
Рейтинг: 0 / 0
02.03.2017, 10:55
    #39413000
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
questionerPetro123,
ммм...да, очевидно верно, но вопрос в другом) непонятно исполнение и использование приведенного кода
тогда не пиши слов концепция и UI выше в твоей фразе. До этого ты как то обходился без этого).
Удачи!
...
Рейтинг: 0 / 0
02.03.2017, 10:56
    #39413001
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
questioner,

Это аналог SwingWorker, только тут как-то намешано всё в кучу и много boilerplate кода. onCompletion вызывается в Event Thread, потому что по завершении задачи мы хотим отобразить результаты в GUI. А GUI у нас однопоточный.
...
Рейтинг: 0 / 0
02.03.2017, 17:58
    #39413315
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
Blazkowiczquestioner,

Это аналог SwingWorker, только тут как-то намешано всё в кучу и много boilerplate кода. onCompletion вызывается в Event Thread, потому что по завершении задачи мы хотим отобразить результаты в GUI. А GUI у нас однопоточный.

Да, вот ещё есть пример использования из книги, который наверное надо показать


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
 private void runInBackground(final Runnable task) {
        startButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                class CancelListener implements ActionListener {
                    BackgroundTask<?> task;
                    public void actionPerformed(ActionEvent event) {
                        if (task != null)
                            task.cancel(true);
                    }
                }
                final CancelListener listener = new CancelListener();
                listener.task = new BackgroundTask<Void>() {
                    public Void compute() {
                        while (moreWork() && !isCancelled())
                            doSomeWork();
                        return null;
                    }

                    private boolean moreWork() {
                        return false;
                    }

                    private void doSomeWork() {
                    }

                    public void onCompletion(boolean cancelled, String s, Throwable exception) {
                        cancelButton.removeActionListener(listener);
                        label.setText("done");
                    }
                };
                cancelButton.addActionListener(listener);
                exec.execute(task);
            }
        });
    }




на вход прилетает final Runnable task которая запускается по нажатию на startButton. Причем важно, что она это делает НЕ в потоке SWING-а

Как задача внутри listenera на cancelButton может повлиять на задачу, что выполняется в отдельном треде в данном примере?
...
Рейтинг: 0 / 0
03.03.2017, 13:00
    #39413637
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Progress and completition indication [JCIP 9.7/9.8]
В общем это ошибка в книге.

http://jcip.net/errata.html

Для меня стало сюрпризом сколько в ней ошибок.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Progress and completition indication [JCIP 9.7/9.8] / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]