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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Последовательно-параллельное выполнение потоков, все выполняются последовательно. 
:(
    Опции темы
Platon
Дата 25.3.2007, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Здравствуйте, уважаемые.

Запускаю задачу. Теоретический сценарий: отрабатывает 1 поток, затем отрабатывают 3 потока, затем 1. В принципе все работает правильно. Вставил sout, чтоб посмотреть как 3 потока переплетаются, и О, чудо! они работают друг за дружкой, единственное изменение - это их порядок выполнения.

Код

public class MyRunnable implements Runnable {
    /**
     * Функция, которая вычисляет значение по аргументу
     * @see #result(double)
     */
    protected Function f;
    /**
     * Владелец, монитор.
     */
    protected Stage owner;

    /**
     *
     * @param f - функция, от которой будет считаться результат
     * @param owner - хозяин, монитор
     */
    public MyRunnable(Function f, Stage owner) {
        setFunction(f);
        setOwner(owner);
    }

    /**
     *
     * @param function - функция, от которой будет считаться результат
     */
    public MyRunnable(Function function) {
        this(function, null);
    }

    /**
     * Установка владельца
     * @param s - хозяин, монитор
     */
    public void setOwner(Stage s) {
        this.owner = s;
    }

    /**
     * Установка функции
     * @param f - функция
     */
    public void setFunction(Function f) {
        this.f = f;
    }
    public void run() {
        Date time1 = new Date();
        double res = 0;
        for (int i = 0; i < 30000; i++) {
            res += result(i);
            if (Tester.DEBUG) {
                if (i % 3000 == 0)
                    System.out.println(this + " current calculation result = " + res);
                Thread.currentThread().yield();
            }
        }
        if (Tester.DEBUG)
            System.out.println(this + " calculation result: " + res);
        synchronized(owner.getStorage()) {
            owner.getStorage().sum += res;
        }
        synchronized(owner) {
            owner.readyThreads++;
            owner.notifyAll();
        }
        Date time2 = new Date();

        if (Tester.DEBUG)
            System.out.println(this + " process time: " + (time2.getTime() - time1.getTime()));
    }

    /**
     * Вычисление фунции
     * @param x - аргумент функции
     * @return результат функции
     * @see #f
     */
    public double result(double x) {
        return f.result(x);
    }

    public String toString() {
        return f.toString();
    }
}


Код

public class Stage {
    /**
     * Следующее звено в цепи вычислений.
     * @see Lab2.Stage
     */
    private Stage next;

    /**
     * набор потоков, выполняющих параллельную рабуоту.
     * @see Lab2.MyRunnable
     */

    private MyRunnable[] threadGroup;

    /**
     * Хранилище данных, является null, если звену не было переданно задание или результат был посчитан
     * @see Lab2.Storage
     */

    protected Storage storage;

    /**
     * Число потоков из группы threadGroup, выполнивших вычисления
     */
    protected int readyThreads;
    /**
     * Приоритет всех потоков
     */
    protected int priority = Thread.NORM_PRIORITY;

    /**
     * Основной конструктор
     * @param next - следующее звено в цепи вычислений
     * @param threadGroup - набор потоков, реализующих текущее задание данного звена
     */
    public Stage(Stage next, MyRunnable[] threadGroup) {
        this.next = next;
        this.threadGroup = threadGroup;
    }

    /**
     * Устанавливает приоритет потоков
     * @param priority - приоритет потока
     */
    public void setPriority(int priority) {
        this.priority = priority;
        if (next != null)
            next.setPriority(priority);
    }

    /**
     * Проверка, готово ли звено принять новое задание
     * @return true - готово, false - не готово
     */
    public boolean isReadyRead() {
        return storage == null;
    }

    /**
     * Проверка, готово ли звено выдать результат
     * @return true - готово, false - не готово
     */
    protected boolean isReadyOutput() {
        return readyThreads >= threadGroup.length;
    }

    /**
     * Возвращает хранилище
     * @return Хранилище данных
     */
    // TODO был синхом
    public Storage getStorage() {
        return storage;
    }

    /**
     * Устанавливает хранилище
     * @param st - хранилище данных
     */
    // TODO был синхом
    void start(Storage st) {
        storage = st;
        for (int i = 0; i < threadGroup.length; i++) {
            Thread t = new Thread(threadGroup[i]);
            t.setPriority(priority);
            t.start();
        }
    }

    

    /**
     * Проверка, есть ли у звена последующее продолжение
     * @return true - продолжение имеется false - отсутствует
     */
    public boolean hasNext() {
        return (next != null);
    }

    /**
     * Ожидает выполнение всех частей задачи, выдача следующего звена цепи вычислений с установленным хранилищем данных
     * @return следующее звено цепи вычислений
     */

    public Stage getNext() {
        while (!isReadyOutput()) {
            try {
                synchronized(this) {
                    wait();
                }
            } catch (InterruptedException e) {}
        }

        readyThreads = 0;
        if (next != null) {

            while(!next.isReadyRead()) {
                synchronized(next) {
                    try {
                        next.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                    }
                }
            }
            next.start(storage);
        }
        storage = null;
        synchronized(this) {
            notifyAll();
        }
        return next;
    }

    /**
     * Устанавливает группу потоков
     * @param threadGroup - группа потоков, вычисляющих подзадачи данного этапа
     */
    public void setThreadGroup(MyRunnable[] threadGroup) {
        this.threadGroup = threadGroup;
    }
}


Код

public class Conveyer {
    /**
     * Входное звено вычислений
     */
    protected Stage startStage;

    /**
     *
     * @param stage - начальное состояниие вычислений
     * @see #startStage
     */

    public Conveyer(Stage stage) {
        startStage = stage;
    }

    /**
     * Основная функция, вычисляет глобальное задание
     * @return результат вычислений
     */
    public double compute() {
        if (Tester.DEBUG) {
            System.out.println("----------------------------------");
            System.out.println("Conveyer: computing sum");
        }
        Storage storage = new Storage();
        Stage cur = startStage;
        synchronized(cur) {
            while (!cur.isReadyRead()) {
                try {
                    cur.wait();
                } catch (InterruptedException e) {}
            }
        }

        cur.start(storage);
        while (cur.hasNext()) {
            cur = cur.getNext();
        }

        synchronized(cur) {
            while (!cur.isReadyOutput()) {
                try {
                    cur.wait();
                } catch (InterruptedException e) {}
            }
        }
        double res = cur.getStorage().sum;
        cur.getNext();
        if (Tester.DEBUG)
            System.out.println("Conveyer: computing result: " + res);
        return res;
    }

    /**
     * Устанавливает приоритет начальному звену
     * @param priority - новый приоритет потока
     */
    public void setPriority(int priority) {
        startStage.setPriority(priority);
    }
}


Код

public class Builder {
    /**
     * Генерация структуры задачи
     * @return входное звено решения задачи
     */
    public static Stage build() {

        Stage stage3 = new Stage(null, null);
        MyRunnable[] thGroup = new MyRunnable[]{new MyRunnable(new P5Function(), stage3)};
        stage3.setThreadGroup(thGroup);

        Stage stage2 = new Stage(stage3, null);
        thGroup = new MyRunnable[]{new MyRunnable(new P2Function(), stage2),
                                 new MyRunnable(new P1Function(), stage2),
                                 new MyRunnable(new P4Function(), stage2)};
        stage2.setThreadGroup(thGroup);

        Stage stage1 = new Stage(stage2, null);
        thGroup = new MyRunnable[]{new MyRunnable(new P3Function(), stage1)};
        stage1.setThreadGroup(thGroup);

        return stage1;
    }
}

Conveyer c = new Conveyer(Builder.build());
c.compute();
Свой вопрос я разрешил с помошью FlasH, очень ему признателен +.
Ну и в принципе, хотелось бы услышать замечания по ныне навороченному коду.

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


Эксперт
***


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

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



После исправления недостатка с параллелизмом, возникла другая проблема.

в некоторых случаях выкидывает эксепшн 
Код

Exception in thread "Thread-32" java.lang.NullPointerException
    at Lab2.MyRunnable.run(MyRunnable.java:71)
    at java.lang.Thread.run(Thread.java:619)


В классе MyRunnable строка 58.

понятно, из-за чего: обращение к null-объекту. Но как он туда затесался? по идее у меня null может быть только в случае, когда задачи нет, но тогда и потоки не запущены, а тут такая ошибочка.
Где это слабое звено? Куда еще поставить синх блоки?

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

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

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


 




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


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

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