Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Организация синхронизированной работы, Допрыгался. 
V
    Опции темы
Prol
Дата 28.1.2008, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 125
Регистрация: 11.1.2008
Где: Кыев, Украина

Репутация: нет
Всего: нет



Цитата(COVD @ 28.1.2008,  19:29)
Prol, java потоки - это воплощение вашей идеи с независимыми приложениями, использующими общую память. 

К сожалению все они рухнут, если произойдёт operation exeption, access violation или overflow в самой JVM.
PM MAIL WWW ICQ   Вверх
COVD
Дата 28.1.2008, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Ничто не вечно. 
PM MAIL   Вверх
Platon
Дата 19.2.2008, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Dear Lord, help me!!!

Я до сих пор не могу найти решения. Мое последнее решение также впадает в ступор:

Код

package platon.network;

import java.util.LinkedList;

public class ResponseWaitor1<E> {
    private final LinkedList<Flag> monitors = new LinkedList<Flag>();
    private final LinkedList<E> queue = new LinkedList<E>();

    public void add(E obj) {
        Flag o;
        synchronized(monitors) {
            while (monitors.isEmpty()) {
                try {
                    System.out.println(Thread.currentThread().getId() + " Waiting monitors");
                    monitors.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            o = monitors.removeFirst();
        }
        System.out.println(Thread.currentThread().getId() + " Monitor passed");
        o.done();
        System.out.println(Thread.currentThread().getId() + " Flag got");
        synchronized(queue) {
            queue.add(obj);
            System.out.println(Thread.currentThread().getId() + " Queue notify");
            queue.notify();
        }
    }

    public E get() {
        Flag o = new Flag();
        synchronized(monitors) {
            monitors.add(o);
            System.out.println(Thread.currentThread().getId() + " Monitor notify");
            monitors.notify();
        }

        while (!o.isDone()) {
            synchronized(o) {
                try {
                    System.out.println(Thread.currentThread().getId() + " Waiting flag");
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(Thread.currentThread().getId() + " Flag passed");

        synchronized(queue) {
            while (queue.isEmpty()) {
                try {
                    System.out.println(Thread.currentThread().getId() + " Waiting queue");
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getId() + " queue passed");
            return queue.removeFirst();
        }
    }

    public static void main(String[] args) {
        final ResponseWaitor1<Integer> waitor = new ResponseWaitor1<Integer>();



        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 2000; i++) {
                    System.out.println(Thread.currentThread().getId() + " " + waitor.get());
                }
            }
        }).start();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 2000; i++) {
                    System.out.println(Thread.currentThread().getId() + " " + waitor.get());
                }
            }
        }).start();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 4000; i++) {
                    waitor.add(i);
                }
            }
        }).start();
    }
}



Добавлено @ 19:11
Я не уверен как правильно называется класс Flag, возможно это некий семафор.

Это сообщение отредактировал(а) Platon - 20.2.2008, 13:12
PM MAIL ICQ   Вверх
SoulKeeper
Дата 19.2.2008, 22:40 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.1.2007
Где: Ukraine, Lviv.

Репутация: 11
Всего: 15



Я конечно понимаю что изобретение своего велосипеда делает программиста более квалифицированым, но есть

1). RMI. Правда кажись работает на блокирующем I/O, в дебри не влезаю, да и для моих потребностей, обслуживание от силы 15 клиентов, мне nio не особо и нужно.
2). JERI в Jini. В свое время обращал внимание, но в глубь копать не стал, т.к. вариант #1 подошел вполне. Кажись есть возможность использование nio.

Собственно вот такие вот дела smile
PM MAIL   Вверх
Platon
Дата 20.2.2008, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Зачем мне ваши технологии, когда я могу без них обойтись. Я с удовольствием перейму стандартное решение текущей задачи, но технологии мне советовать не надо.
PM MAIL ICQ   Вверх
SoulKeeper
Дата 20.2.2008, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 14.1.2007
Где: Ukraine, Lviv.

Репутация: 11
Всего: 15



Вообще-то это и есть стандартные решения текущей задачи.

Это сообщение отредактировал(а) SoulKeeper - 20.2.2008, 11:07
PM MAIL   Вверх
Platon
Дата 20.2.2008, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



задача сводится лишь к тому чтобы из асинхронной работы была возможность запросить и дождаться ответа от общего объекта, причем в пределах одной JVM. Спрашивается зачем мне RMI???

Это сообщение отредактировал(а) Platon - 20.2.2008, 11:30
PM MAIL ICQ   Вверх
Platon
Дата 20.2.2008, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Последнее из выведенного на экран оказывается всегда похожим на

Код

11 Monitor passed
11 Flag got
11 Queue notify
11 Waiting monitors
10 Waiting flag


Всегда заканчивается ожиданием готовности флажка. и почему то в этот момент он не срабатывает :( хотя во 2-й строчке он уже был выброшен.

PM MAIL ICQ   Вверх
Platon
Дата 22.2.2008, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Вот оно!!! Как говорится: "Эврика"!!!

Код

public class ResponseWaitor1<E> {
    private final LinkedList<Flag> monitors = new LinkedList<Flag>();
    private final LinkedList<E> queue = new LinkedList<E>();

    public void add(E obj) {
        Flag o;
        synchronized(monitors) {
            while (monitors.isEmpty()) {
                try {
                    //System.out.println(Thread.currentThread().getId() + " Waiting monitors");
                    monitors.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            o = monitors.removeFirst();
        }
        //System.out.println(Thread.currentThread().getId() + " Monitor passed");
        o.done();
        //System.out.println(Thread.currentThread().getId() + " Flag got");
        synchronized(queue) {
            queue.add(obj);
            //System.out.println(Thread.currentThread().getId() + " Queue notify");
            queue.notify();
        }
    }

    public E get() {
        Flag o = new Flag();
        synchronized(monitors) {
            monitors.add(o);
            //System.out.println(Thread.currentThread().getId() + " Monitor notify");
            monitors.notify();
        }

        synchronized(o) {
            while (!o.isDone()) {
                try {
                    //System.out.println(Thread.currentThread().getId() + " Waiting flag" + o.isDone());
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        //System.out.println(Thread.currentThread().getId() + " Flag passed");

        synchronized(queue) {
            while (queue.isEmpty()) {
                try {
                    //System.out.println(Thread.currentThread().getId() + " Waiting queue");
                    queue.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //System.out.println(Thread.currentThread().getId() + " queue passed");
            return queue.removeFirst();
        }
    }

    public static void main(String[] args) {
        final ResponseWaitor1<Integer> waitor = new ResponseWaitor1<Integer>();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 40000; i++) {
                    waitor.add(i);
                }
            }
        }).start();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 20000; i++) {
                    System.out.println(Thread.currentThread().getId() + " " + waitor.get());
                }
            }
        }).start();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 20000; i++) {
                    System.out.println(Thread.currentThread().getId() + " " + waitor.get());
                }
            }
        }).start();
    }
}


Жаль, что мне никто не помог, и столько времени пришлось ломать голову над этим пустячком.
Проблема оказалась вот в этом куске:

Код

 while (!o.isDone()) {
            synchronized(o) {
                try {
                    System.out.println(Thread.currentThread().getId() + " Waiting flag");
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }


Поменял на 

Код

synchronized(o) {
            while (!o.isDone()) {
                try {
                    //System.out.println(Thread.currentThread().getId() + " Waiting flag" + o.isDone());
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }


Добавлено через 10 минут
Я бы сам себе за такие мучения орден вручил бы!

Это сообщение отредактировал(а) Platon - 22.2.2008, 13:28
PM MAIL ICQ   Вверх
COVD
Дата 22.2.2008, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Очень удобен для таких задач класс java.util.concurrent.LinkedBlockingQueue - никаких wait и synchronized не нужно. Единственное неудобство - эта очередь не принимает на входе null. Поэтому конец очереди , если есть в нем необходимость, можно определить только поставив в очередь специальный обьект и ловить его на выходе через instanceof  .
PM MAIL   Вверх
Platon
Дата 22.2.2008, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



COVD, дорогой, где ж вы неделю назад были???!!!
PM MAIL ICQ   Вверх
COVD
Дата 22.2.2008, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Я просто не сразу понял, с чем вы сражались.  smile 

Еще мне кажется, вы не предусмотрели таймаут на ожидание ответа. Ответ ведь может никогда и не придти. А в LinkedBlockingQueue  его можно поставить и тогда, если время ожидания ответа превысит таймаут, очередь выбросит null (поэтому null и запрещен на входе).

Это сообщение отредактировал(а) COVD - 22.2.2008, 17:50
PM MAIL   Вверх
Platon
Дата 22.2.2008, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



Смотрим сюда.
Код

public class ResponseWaitor1<E> {
    private LinkedBlockingQueue<E> queue = new LinkedBlockingQueue<E>();

    public void add(E obj) {
        queue.add(obj);
    }

    public E get() {
        return queue.poll();
    }

    public static void main(String[] args) {
        final ResponseWaitor1<Integer> waitor = new ResponseWaitor1<Integer>();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 40000; i++) {
                    waitor.add(i);
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {

                }
                System.out.println("There are " + waitor.queue.size() + " items left in queue");
            }
        }).start();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 20000; i++) {
                    System.out.println(Thread.currentThread().getId() + " " + waitor.get());
                }
            }
        }).start();

        new Thread(new Runnable() {
            int i;
            public void run() {
                for (int i = 0; i < 20000; i++) {
                    System.out.println(Thread.currentThread().getId() + " " + waitor.get());
                }
            }
        }).start();

        
    }
}


Теперь смотрим на конец вывода в консоль:

Цитата

10 39988
10 39989
10 39990
10 39991
10 39992
There are 7 items left in queue

проблемка возникла... судя по всему, в некоторые некоторые моменты poll() выдают одинаковый результат 2-м потокам.
PM MAIL ICQ   Вверх
COVD
Дата 22.2.2008, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



у меня ваш код нормально сработал - последнее выведенное число 39999. А надпись "There are .." выскакивает где-то в середине вывода на консоль, т.е. это еще не конец работы программы.

Это сообщение отредактировал(а) COVD - 22.2.2008, 18:36
PM MAIL   Вверх
Platon
Дата 22.2.2008, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1801
Регистрация: 25.4.2006

Репутация: 16
Всего: 40



не-не, надо несколько раз прогу запустить + если где-то в середине, увеличьте задержку до 10 секунд.
PM MAIL ICQ   Вверх
Страницы: (4) Все 1 2 [3] 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1003 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.