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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки и критичный по времени код, Блокирование потока из другого 
:(
    Опции темы
Max_1_
Дата 28.4.2009, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.3.2007

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



Здравствуйте!

Появилась проблема с работой критичного по времени кода. В программе работает несколько постоянных потоков и периодически запускаются временные. Программа считывает команды из последовательного порта и мне необходимо ускорить этот процесс.
Иногда он выполняется быстро, когда не работает большинство потоков, но это редко. Хотелось бы както заблокировать потоки, которые мне надо, на время пока работает обмен командами. Не могу придумать как это сделать. 
Приходит в голову только такой метод: проверять наличие потока обмена командами в потоках которые хочу блокировать и при его наличие вызывать join(). Но он слишком загромоздит код, ведь это надо будет по всему коду такие проверки повставлять.

Вообще насколько понял я могу заблокировать чужой поток, только в самом чужом потоке, а не из вне. :(

Прошу помощи. Кто что может подсказать.
PM MAIL   Вверх
W0LF
Дата 29.4.2009, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

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



А можно какой-нидь пример кода или схему? ато на словах не особо воспринимается


--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
eugine_s
Дата 29.4.2009, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Попробуй выставлять приоритеты потокам.

Тот, который критичный, ставь MAX_PRIORITY, а остальным меньшие приоритеты. 

У меня как-то была чем-то похожая проблема, решилось установлением приоритетов потоков.
PM MAIL   Вверх
Max_1_
Дата 29.4.2009, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.3.2007

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



Цитата(eugine_s @  29.4.2009,  14:11 Найти цитируемый пост)
Попробуй выставлять приоритеты потокам.

Тот, который критичный, ставь MAX_PRIORITY, а остальным меньшие приоритеты. 

У меня как-то была чем-то похожая проблема, решилось установлением приоритетов потоков. 


Да, пока так и работает. Но плохо помогает.

to WOLF: Код если выкладывать, то много придется.
Попробую получше обьяснить. Есть несколько постоянных потоков А, В и С. Есть временные потоки D, E, F. И есть поток который запускается из системы G. 
G должен быстро выполняться. Поэтому охото заблокировать A,B,C и если есть D,E,F пока выполняется G. Как это можно реализовать или посоветуйте куда копать.


PM MAIL   Вверх
W0LF
Дата 30.4.2009, 02:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

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



Тут по ходу просто приоритетами не обойтись. надо именно делать приостановку потоков.
Я бы сделал примерно так:
Код

public class MyThread extends Thread {
    private boolean finished = false;
    private boolean stop = false;
    private boolean pause = false;
    private static final Object objectMonitor = new Object();


    public MyThread(String name) {
        setName(name);
        this.start();
    }

    public void callBack() {

    }

    public void run() {
        while (!stop) {
            while (pause) {
                synchronized (objectMonitor) {
                    try {
                        System.out.println(getName() + " thread has been paused");
                        callBack();
                        objectMonitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println(getName() + " thread is doing something");
        }
        finished = true;
        callBack();
        System.out.println(getName() + " thread has been finished");
    }

    public void tPause() {
        synchronized (objectMonitor) {
            pause = true;
            objectMonitor.notify();
        }
    }

    public void tContinue() {
        synchronized (objectMonitor) {
            pause = false;
            objectMonitor.notify();
        }
    }

    public void tStop() {
        synchronized (objectMonitor) {
            stop = true;
            pause = false;
            objectMonitor.notify();
        }
    }

    public boolean isFinished() {
        return finished;
    }

    public boolean isPaused() {
        return pause;
    }
}



import java.util.Vector;
import java.util.Enumeration;

public class ThreadsContainer implements Runnable {
    private Vector threads;
    private static final Object objectMonitor = new Object();

    public ThreadsContainer() {
        threads = new Vector();
        //optional - remove all threads that has been finished
        //new Thread(this).start();
    }

    public void addThread(Thread thread) {
        threads.add(thread);
    }

    public void removeThread(Thread thread) {
        threads.remove(thread);
    }

    public void pauseAllThreads() {
        Enumeration e = threads.elements();
        while (e.hasMoreElements()) {
            MyThread tempThread = (MyThread)e.nextElement();
            tempThread.tPause();
        }
    }

    public void continueAllThreads() {
        Enumeration e = threads.elements();
        while (e.hasMoreElements()) {
            MyThread tempThread = (MyThread)e.nextElement();
            tempThread.tContinue();
        }
    }

    /**
     * optional
     * check threads, if thread is finished it will be deleted from collection.
     */
    public void run() {
        //todo change this condition to stop this thread
        while (true) {
            while (threads.isEmpty()) {
                synchronized (objectMonitor) {
                    try {
                        objectMonitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            Enumeration e = threads.elements();
            while (e.hasMoreElements()) {
                MyThread tempThread = (MyThread)e.nextElement();
                if (tempThread.isFinished()) {
                    threads.remove(tempThread);
                }
            }
        }
    }

}




//ну и как-то так

final ThreadsContainer tc = new ThreadsContainer();
        tc.addThread(new MyThread("A"));
        tc.addThread(new MyThread("B"));
        tc.addThread(new MyThread("C"));
        tc.addThread(new MyThread("D"));
        tc.addThread(new MyThread("E"));
        tc.addThread(new MyThread("F"));

        tc.pauseAllThreads();
   
        MyThread myThreadG = new MyThread("G") {
            public void callBack() {
                tc.continueAllThreads();
            }
        };
       
        myThreadG.tStop();//or myThreadG.tPause();
       




--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
zzzvyk
Дата 30.4.2009, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А это ничего, что isFinished не синхронизирован?
я бы сделал finished volatile. Но это ИМХО...

Добавлено через 12 минут и 24 секунды
Немного подумав я пришел к заключению, что 
    private boolean finished = false;
    private boolean stop = false;
    private boolean pause = false;

должны бы быть volatile;
 
потому что, например один поток может запросить tPause(), tConitnue(), tStop(), а другой в это время проверить статус - получается что данные он получит устаревшие? Или как?

Это сообщение отредактировал(а) zzzvyk - 30.4.2009, 11:23
PM MAIL Skype   Вверх
W0LF
Дата 30.4.2009, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

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



Да, пропустил, но в данном случае - не критично(там для этого есть цикл, который каждый раз идет по всем потокам и проверяет финишд они или нет).
тогда лучше так
Код

 public void synchronized run() {

 public boolean synchronized isFinished() {



--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
zzzvyk
Дата 30.4.2009, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



тада у тебя получается 2 монитора 
 this
 objectMonitor

как результат - IllegalMonitorStateException, ИМХО.

вообще я бы посоветовал сходить на сайт Doug Lea и проанализировать готовые решения. Для Java1.5 они  уже устарели, для телефонов - самое оно (ну, возможно немного тяжеловатые, но это лучше чем криво)
 
 
PM MAIL Skype   Вверх
Max_1_
Дата 30.4.2009, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 23.3.2007

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



Большое спс Wolf за код, буду пробовать у себя.

А что вы посоветуете если у меня DoingSomething в потоке, продолжительный. Где-то минуту.
Просто код выполняется на контроллере, и он довольно медленный.

PM MAIL   Вверх
W0LF
Дата 30.4.2009, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

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



zzzvyk, как Вы выразились - по Вашему скромному мнению Вы считаете что будет IllegalMonitorStateException, я думаю что Вам так и следует оставаться при своем скромном мнении, столько критики и ни одного дельного совета. Такое чувство что Вы недавно начитались книжек умных, но на практике еще не успели применить. Объясните как можно получить IllegalMonitorStateException, если он бросается только методами wait и notify?
Цитата

IllegalMonitorStateException - if the current thread is not the owner of this object's monitor.


Цитата(zzzvyk @  30.4.2009,  17:38 Найти цитируемый пост)
но это лучше чем криво)

спасибо за лаконичный комментарий к моему коду, надеюсь, Вы пишите намного лучше.

Добавлено через 1 минуту и 59 секунд
Цитата(Max_1_ @ 30.4.2009,  19:02)
А что вы посоветуете если у меня DoingSomething в потоке, продолжительный. Где-то минуту.
Просто код выполняется на контроллере, и он довольно медленный.

я думаю что кусок кода
Код

while (pause) {
                synchronized (objectMonitor) {
                    try {
                        System.out.println(getName() + " thread has been paused");
                        callBack();
                        objectMonitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

вставить просто где-нидь еще, то есть чтоб было пару мест, где можно приостановить выполнение потока


--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
W0LF
Дата 30.4.2009, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

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



Цитата

 public void synchronized run() {
 public boolean synchronized isFinished() {

этого все-таки делать нельзя - будет дедлок.
например один поток зайдет в run, у него будет две критический секции на this и на оbjectMonitor,  вторую он освобождает, а первую - нет, и когда кто-то попросит isFinished то он будет долго и нудно ждать.
тут лучше синхронизировать по отдельности или же volatile


--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
math64
Дата 1.5.2009, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



а разве в j2me можно использовать volatile?
PM   Вверх
W0LF
Дата 1.5.2009, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


alexander lonsky
***


Профиль
Группа: Участник
Сообщений: 1164
Регистрация: 9.2.2006
Где: Ukraine.Dnepropet rovsk

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



по крайней мере не ругается, а проверить правильность выполнения - сейчас пока нет времени, если честно - я и в большой джаве никогда его не использовал, пользовался синхронизацией


--------------------
iOS developer
PM MAIL WWW Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

  • Прежде чем задать вопрос прочтите это!
  • Литература по Java находится здесь.
  • Литературу по Java обсуждаем здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда

  • FAQ раздела лежит здесь!
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java ME (J2ME) | Следующая тема »


 




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


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

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