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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Последовательный запуск Thread, Разными объектами одного класса 
V
    Опции темы
AbdulBcex
Дата 30.6.2010, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Всем здравствовать!

Наткнулся тут на проблему. Есть класс наследующий класс, который имплементирует Runnable. Делаю @Override метода run();
Код

public void run() {

try{ 
Thread.sleep(OFFSET);
}catch(InterruptedException e1){}

while(condition) //Что бы это значило, кстати?
      while(active){
                 something.doSomethingElse();
                 .........
}
}

Код с комментами взят из метода суперкласса, я его не трогал. Объясните, пожалуйста, что это значит?
А собственно вопрос таков. Я делаю несколько объектов класса. У каждого вызываю метод start(), один за другим. Нужно, чтобы первый объект сразу переходил "к делу" - у него OFFSET = 0, у второго - 25 (50 и 75 у других соответственно). Смотрю на данные логов - ну свистопляска чистой воды! Первые значений 20 выходят практически ровно, разница в сотых долях. Потом такие скачки начинаются, аж жуть. Забавно, но ведь по идее один поток стартует сразу, второй спит 25 мс...
Причем делаю на разных компьютерах, на одном JVM специально выделено отдельное ядро и гигабайт оперативки - всегда разный результат и те же скачки. Попробовал Thread.sleep(OFFSET, 0);, так он мне потом вообще разницу в 7(!) мс вместо 25 выдал. 

Поискал тут на форуме, видел похожие темы, но они либо старые, либо не совсем то. Подскажите, пожалуйста, где поискать-посмотреть-почитать, что ли.


Это сообщение отредактировал(а) AbdulBcex - 30.6.2010, 18:10
PM MAIL   Вверх
LSD
Дата 30.6.2010, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



1. sleep() не гарантирует что поток будет остановлен ровно на Х мсек. Это время приблизительное. И вообще он может проснутся раньше, смотри документацию.
2. Разрешаюшая способность таймера тоже не 1 мсек, а больше, под виндой это где-то 10 мсек.
3. Нет никаких гарантий на тему того, как система будет переключать потоки. Даже если у тебя N потоков и N ядер, это вовсе не гарнтирует что каждому потоку будет выделенно отдельное ядро и они на самом деле будут выполнятся паралельно. А уж в случае одного ядра, переключение между потоками просто гарантированно. Плюс запись логов задача связанная с блокировками на синхронизацию, обращение к внешним ресурсам (например система IO), что так же вызывает переключение потоков.

Если ты хочешь получить какой-то гарантированный порядок - используй синхронизацию или java.util.concurrent.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Skipy
Дата 30.6.2010, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Почитайте про синхронизацию: http://www.skipy.ru/technics/synchronization.html


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
AbdulBcex
Дата 1.7.2010, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо за советы.

На самом деле синхронизация действительно единственное, что приходит в голову. Но она требует объект, которого нет, который нужно сделать только для синхронизации. Опять же блоки synchronize и т.д., которые не ясно где ставить, метода main у меня нет, потоки принадлежат разным объектам одного класса, которые между собой никак не взаимодействуют, и не особо радует перспектива это взаимодействие создавать. 

Нужно-то всего лишь притормозить запуск каждого следующего потока на данное количество мс. Я делал до четырех потоков, так несмотря ни на что (на их количество и параллельную работу, например), данные они возвращали четко с заданной переодичностью, то есть data(i) - data(j) = const мс.

В общем, думаю дальше.
PM MAIL   Вверх
LSD
Дата 1.7.2010, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Так чего тебе все таки надо: организовать паралельную работу нескольких потоков или красиво вывеси в консоль:
Цитата
поток 1
поток 2
поток 3

через заданные интервалы времени?

Если второе то просто используй java.util.Timer.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
AbdulBcex
Дата 2.7.2010, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Да видимо объяснить толково не очень выходит smile .

Есть n потоков. Каждый поток организуется n-ным объектом класса:
Код

obOfClass1.start(); //В методе старт создается поток, если он уже не существует и потом соответственно thread.start();
obOfClass2.start();
...
obOfClassn.start();
 

Каждый следующий поток стартует через OFFSET = n*25 мс (т.е. 0 - сразу, 1 - 25 мс, 2 - 50, 3 - 75 мс и т.д.) начинает давать данные с периодом Т.
OFFSET я задаю через 
Код

run(){
try{//самое начало метода run()
Thread.sleep(OFFSET);
}catch(...){...}
...
...
...


Ну а дальше уже внутри метода есть считалки через System.nanoTime() дающие тот самый период. И все бы было ничего, если б не восьмой этаж и то, что где-то в середине именно считалки дают сбой - т. е. вместо T идет период T+(-)some_time. Такого рода отклонения ловятся с помощью прибавки/убавки времени. Т.е. в следующий раз компенсируется с помощью T-(+)some_time. 
Вот. Такие дела. Выглядит сложновато, наверное, но как по мне, так это проще, чем выдумывать синхронизацию на пустом месте. В принципе, работает. Сейчас свистопляски не наблюдается особой. Более менее приближено к прямой, даже средние значения T лежат в пределах +-10мс, (хотя и то много, но это максимум, что наблюдал до сего времени). 

Еще не видел, что такое java.util.cocurrent, но если про параллельную работу с объектами, то мне как-то не очень.
PM MAIL   Вверх
LSD
Дата 2.7.2010, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Цитата(AbdulBcex @  2.7.2010,  15:05 Найти цитируемый пост)
Ну а дальше уже внутри метода есть считалки через System.nanoTime() дающие тот самый период. И все бы было ничего, если б не восьмой этаж и то, что где-то в середине именно считалки дают сбой - т. е. вместо T идет период T+(-)some_time. Такого рода отклонения ловятся с помощью прибавки/убавки времени. Т.е. в следующий раз компенсируется с помощью T-(+)some_time. 

А в чем логика приложения то? Поток должен отсчитать N мсек, вывести сообщение и заснуть?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
AbdulBcex
Дата 5.7.2010, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

А в чем логика приложения то? Поток должен отсчитать N мсек, вывести сообщение и заснуть? 


Не совсем. Поток генерирует данные, раз в 100 мс, с временными отметками (timestamp), каждый - свои (т.е. неодинаковые), а потом передает их дальше (не другим потокам, а дальше по цепочке). Задержка нужна, чтобы более четко и вовремя заполнять стеки приемников данных, поскольку данные, к примеру, первого потока будут идти дольше - их еще обработать нужно, в то время как данные четвертого идут сразу в стек приемника.


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

Хотя уже сейчас вижу, что в принципе это нелегко даже с синхронизацией. Стало лучше, но до нормальных (и более менее постоянных) результатов еще далеко.

Это сообщение отредактировал(а) AbdulBcex - 5.7.2010, 17:36
PM MAIL   Вверх
AbdulBcex
  Дата 7.7.2010, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



И снова здравствуйте!!! Извиняюсь, что "бужу" тему.

Подскажите, пожалуйста, как синхронизировать разные потоки, созданные разными объектами одного класса. 
Я слегка замумукался - все примеры идут для синхронизации объекта или метода одного класса, для доступа потоками других классов. 
Мне же нужно, по сути, синхронизировать внутри одного метода run(), выполняемого в последствии каждым из этих потоков.
Вот мой код:
Код

public class MyClass(){

Object sync = new Object();
...
boolean canProceed = true;
volatile int FLAG = 0;
int ID, OFFSET;// См. объяснение задачи выше
...
MyClass(int threadID, int OFFSET){
this.ID = threadID;
}

run(){
try{
Thread.sleep(OFFSET)}catch(...){...}//Каждый поток вначале засыпает на время (у первого OFFSET = 0, у второго - 25 и т.д.)

synchronized(sync){ //Начинается "синхронизированный" (в теории :wacko ) блок
while(!canProceed && ID == FLAG){//Идет проверка и вызов wait(); FLAG по идее должен пускать поток следующий за нынешним
//Изначально FLAG = 0 для первого потока
try{
sync.wait();
}catch(...){...}

canProceed = false;//поток зашел и тут же сменил основной "проходной параметр". 
//Начальная задержка на OFFSET и FLAG = 0 практически гарантирует, что первым будет именно поток с ID = 0 (в теории)
performMainAction();

sync.notify();//Поток заканчивает работу в синхронизированном блоке
canProceed=true;

if(ID == 0) FLAG = 1;//FLAG меняется на следующий
else if(ID == 1) FLAG = 2;
...
else if(ID == n) FLAG = n+1;

}
}


Путем экспериментов выяснил, что
  • Период Т, о котором говорил выше, сохраняется и потоки работают более менее параллельно.
  • Предыдущее утверждение верно не всегда. Если время работы программы более 2-3х минут, например...
  • Цикл while вообще не посещается потоками... Но при этом см. пункт 1.
  •  I need help... smile


Это сообщение отредактировал(а) AbdulBcex - 7.7.2010, 12:49
PM MAIL   Вверх
4EJIOBEK
Дата 8.7.2010, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ваш класс не описывает интерфейс Runnable  не является наследником Thread. 
Как вы используете свой класс(стартуете его в потоке)?
PM MAIL ICQ   Вверх
AbdulBcex
Дата 8.7.2010, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

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

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


 




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


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

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