Рассмотрим стандартную ситуацию: Приложению нужно загрузить из сети данные. Это обычно делается в отдельном потоке: главный поток запускает вспомогательный и в этом вспомогательном потоке загружается необходимая информация. По окончании загрузки информации класс вспомогательного потока должен уведомить об этом класс главного потока, чтобы тот мог начать обработку данных. Как это сделать? Я вижу два подхода. Какой из них правильнее не знаю. Первый подход (псевдокод): Код (Text): interface DataWaiter // Интерфейс ожидания данных { DataReceived(); } class MainClass implements DataWaiter { boolean m_bDaraReceived; main() { m_bDaraReceived = false; DataReceiver dr = new DataReceiver(); dr.loadData(this); while (!m_bDataReceived) { Sleep(1000); } Data data = dr.getData(); processData(data); } DataReceived() { m_bDataReceived = true; } processData(Data data) { // Сложные манипуляции с данными } } class DataReceiver { Data data; loadData (DataWaiter observer) { beginThread // Получаем данные из сети data = ... observer.DataReceived(); endThread } Data getData() { return data; } } Главный поток запрашивает данные и ждёт пока они будут получены. Напрашивается вопрос - а на кой тогда отдельный поток, если главный в это время всё равно простаивает?? Тогда немного изменим код: Код (Text): interface DataWaiter // Интерфейс ожидания данных { DataReceived(); } class MainClass implements DataWaiter { main() { m_bDaraReceived = false; DataReceiver dr = new DataReceiver(); dr.loadData(this); // Дальше можно заниматься чем угодно. } DataReceived() { Data data = dr.getData(); processData(data); // Всё это будет выполняться во вспомогательном потоке! } processData(Data data) { // Сложные манипуляции с данными } } class DataReceiver { Data data; loadData (DataWaiter observer) { beginThread // Получаем данные из сети data = ... observer.DataReceived(); endThread } Data getData() { return data; } } Вроде бы ничего фатального - все при делах. Но то, что обработка данных тоже будет происходить во вспомогательном потоке меня настораживает, т.к. я подразумевал, что вспомогательный поток будет только загружать данные, а обработка (которая может занимать кучу времени) - это уже не его дело. Иначе получится так, что я не буду знать какой метод в каком потоке у меня выполняется. Часть метододов обработки может вызываться из главного потока, а часть будет вызвана вспомогательным. Это мне не нравится, хотя явных препятствий этому я не вижу. PS просьба обсуждать эту проблему так, как она дана, т.е. в асбстрактном плане, не касаясь конкретных механизмов того или иного языка или той или иной программной среды. Например события (Events) в моём случае применить нельзя, поэтому подобные "решения из коробки" неинтересны.
Booster Я затрудняюсь конкретно ответить на этот вопрос. В моей конкретной ситуации возможно и не к чему создавать отдельный поток. Однако есть общее правило, что во избежание зависания основной логики программы и т.д. и т.п. загрузку данных из сети следует выполнять в отдельном потоке. n0name Так и есть. Я пишу на J2ME и изъясняться мне сейчас проще на джаваподобном наречии. Но это всё таки псевдокод, ибо скомпилировать вышеприведённые кодесы вряд ли удастся.
Green_DiCk Если именно от зависания основной логики, то в простешейшем случае можно крутить её в цикле, совершая полезную работу и проверяя объект синхронизации. А вообще тут никак лучше подходит событийная модель, не обязательно операционной системы, можно её организовать самостоятельно. Некие компоненты которые обрабатывают свои очереди сообщений(аля окна в винде), главный цикл который вызывает методы обработки очередей компонентов(аля ось). Компоненты могут друг другу передавать в очереди сообщения(аля SendMessage).
Booster Пожалуй в этом направлении и буду работать. Эта мысль у меня присутствовала, но по непонятной причине (хотя так часто бывает) я её не рассматривал серьёзно. Спасибо что ткнул меня куда надо. Собственная система событий в любом случае будет полезна, т.к. стандартная модель событий в MIDP очень ограничена.
Где можно почитать про написание собственного класса Event? Или какой-нибудь пример достойный, в котором грамотно реализовано (на любом языке). Хочется семь раз изучить, один раз накодить. Погуглил, но пока ничего вразумительного. Если есть книжка какая-нибудь, то вообще здорово.
Green_DiCk А чем занят "главный поток", пока ожидаются данные? Что это за приложение? Такого правила нет. Booster Все уже давно придумано.
к примеру, если нужно что-то вроде фреймворка с одним и тем же интерфейсом и в kernel mode, и в user mode, то скорее всего придется с 0 писать