Как синхронизировать главный поток и другой?

Ответить
Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Как синхронизировать главный поток и другой?

Сообщение Prospekt » 11 июн 2012, 22:28

Как посылать сообщения из собственного потока мы знаем, для этого используется например, Handler. Вопрос в том, как сделать наоборот, т.е. из главного потока послать сообщение собственному потоку?

Хочу что-то типа такого:

Код: Выделить всё

public void run() {
        isRun=true;
        handler = new Handler();
          
        while(isRun){
            // (***) Обработка внешний событий
            doSomeThing();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(SecondHandler.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
Где вместо "(***)" находится код, который берет сообщения и обрабатывает пока они не закончатся.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Как синхронизировать главный поток и другой?

Сообщение damager82 » 13 июн 2012, 10:46

Prospekt писал(а):из главного потока послать сообщение собственному потоку?
Собственный поток может быть расширением стандартного Thread и содержать методы, которые нам нужны. Через них можно взаимодействовать.
Или вопрос в другом?
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Prospekt
Сообщения: 41
Зарегистрирован: 30 май 2012, 23:06

Re: Как синхронизировать главный поток и другой?

Сообщение Prospekt » 13 июн 2012, 11:21

Вопрос в том, как взаимодействовать с собственным потоком потокозащищенным способом.

Я могу заставить выполнить мой поток некий код (поместив его в методе класса расширяющего Thread), и вызвать этод метод из другого потока. Проблем в том, что этот метод будет выполнен всеравно в том потоке в котором он вызван.

Смотри, если у моего потока-класса есть метод doLyalya(), то если я просто вызовы этот метод из главного UI потока, то и обрабатываться он будет в главном потоке, а не в кастомном. Если передавать сообщения (или их подобие) через переменные или флаги, то возможны варианты, когда один поток будет устанавливать эти переменные, а другой считывать. В этом случае возможны повреждения целостности данных. Например есть поля "Name" и "Email". Теперь один поток устанавливает значения, а второй их считывает. Что произойдет, если второй поток считает данные между тем, как первый поток будет их устанавливать. Т.е. второй поток считает оба поля после того, как первый установит первое, но перед тем, как он же установит второе поле.

Код: Выделить всё

// установка значений
name="Vasya";
email ="vasya@gmail.com";
Получается, что считывающий поток получит новое значение "name" и старое значение "email".
По стандарту данная пробема должна решаться через synchronized. Проблема в том, что блокировать основной поток нельзя!!!! поэтому нельзя делать сеттер потокозащищенным с помощью оператора synchronized.

Вот если бы можно было ложить сообщения в очередь, а потом в нужном потоке эти сообщения из неё забирать, было бы то, что надо. Handler использует такую очередь, но она использует нативную синхронизация, которая не блокирует потоки. В java же такую синхронизацию сделать нельзя своими силами.

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Как синхронизировать главный поток и другой?

Сообщение damager82 » 13 июн 2012, 12:05

Попробуй тут глянуть: http://developer.android.com/resources/ ... ments.html

Там вроде как раз то, что тебе нужно. Создается HandlerThread и используется его очередь для обработки.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Ответить