Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Итератор в отдельной нити.


Автор: AndryG 31.3.2010, 15:39
Доброго.
Имеем класс журнала(Journal), который содержит коллекцию (arraylist) классов-задач(Task)

Один из методов журнала perform(), запускается в отдельной нити, проходит итератором по всем задачам и, для избранных, запускает доп. нити выполнения задач.

Как организовать синхронизированную работу основной нити, которая может изменять журнал и содержащиеся в нем задачи и нити с методом perform() ? 
С чего начать? Поголовно во все методы тыкать synchronized ?
Почитал про синхронизацию ... вроде как всё ясно, но на своем примере ... туплю :(


Автор: LSD 31.3.2010, 16:34
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html спасет отца русской демократии.

Автор: AndryG 31.3.2010, 18:45
Жаль я не тот самый Отец smile
Блокирующая очередь красиво выглядит в http://forum.vingrad.ru/forum/topic-295938/kw-%D0%BF%D0%BE%D1%82%D0%BE%D0%BA.html

Я думаю, что применение очереди для  хранения списка заданий в моем планировщике не в тему ... тут никто не входит и выходит ... элементы удаляются из середины списка.

Ещё мысль. Блокирующая очередь защищает от беспредела в её составе, но ведь она не даст мне защиты в изменении содержимого её элементов.

Метод perform() класса Journal
Код
    public void perform() throws TaskManagerException {
        int now = new Time().asInt(); // получаем текуще время с секундах от начала суток (Time не библиотечный класс)
        if (!isEnabled() || prevPerformTime == now){ // откл. или для этого момента времени планировщик уже отработал ранее ...
            return; // ... прерываем метод
        }
        System.out.println("->["+now+"]");
        for (Task task : this) { // итератор класса возвращает итератор поля ArrayList<Task> journal
            if (task.isEnabled() // задание включено и время его между предыдущим запуском метода и "сейчас" ...
                    && task.getTime().asInt() > prevPerformTime
                    && task.getTime().asInt() <= now) { ... значит запускаем задание
                performerFactory.newPerformer(task).start();    System.out.println("RUN!"+task.getName());                
            }
        }
        prevPerformTime = now; // запоминаем момент теперь уже прошлой отработки метода
    }

Именно этот кусок кода я хочу периодически запускать в отдельной нити.
Внешний код, может как изменить кучку упоминаемых здесь полей (int prevPerformTime, boolean enabled, ArrayList<Task> journal) так и "содержимое содержимого" списка (объекты Task) тоже могут быть отредактированы.

Можно нарваться на ConcurrentModificationException ... в данном случае я могу смирится с этим и запустить итератор вновь ... а как быть с изменением элементов списка?

Блин! Я и вопрос задать не могу нормально, ибо не знаю с чего тут начинать думать. Подтолкните меня, пжлст smile

Добавлено через 4 минуты и 29 секунд
Епт. Не могу я рестартовать итератор
Код
        iteratorRestart:
        try{
            for (Task task : this) {
                    //...
            }
        }catch (ConcurrentModificationException e) {
            break iteratorRestart; //изменилось содержимое
        }
 так я получу двойную отработку заданий, которые успели проскочить до исключения

Добавлено через 7 минут и 50 секунд
Не отправляйте меня, пжлст, к java.util.concurrent.concurrent*  smile

Автор: LSD 1.4.2010, 13:38
Цитата(AndryG @  31.3.2010,  19:45 Найти цитируемый пост)
Я и вопрос задать не могу нормально, ибо не знаю с чего тут начинать думать. Подтолкните меня, пжлст

С описания задачи, типа:
- есть набор тасков которые надо запускать в определенное время
- у таска есть время запуска, ....
- таск может в любой момент времени быть измененным сторонним процессом
....

как-то так smile

Автор: ivanovpv 1.4.2010, 15:28
Посмотри в сторону http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html.

далее, чтобы не вызвать ConcurrentModificationException  у тебя есть метод Thread.checkAccess() можно заранее проверять на возможность несинхронизированного доступа и обходить проблемные места.

Автор: LSD 2.4.2010, 16:07
А ThreadGroup тут с какого бока может помочь?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)