LINUX.ORG.RU

простейшая синхронизация потоков

 ,


0

2

Добрый день!

Помогите мне, пожалуйста, с откровенно детским вопросом по Java. Имеем :

public class MyActivity extends Activity {
    ...
    private class MyThread extends Thread {
        public void run() {
           // читаем из последовательного порта
           ...

           if( crc ) {
               onDataReceived( data, data.length );
           }
        }
    }
   
    protected void onDataReceived( final byte[] buffer, final int size )
    {
         // обрабатываю
    }

}

Как Вы уже могли догадаться, данный код работает под Android и читает данные из последовательного порта. Проблема заключается в том, что иногда (примерно в 1ом и 3-4 случаев) данные до метода onDataReceived добираются битыми. Подозреваю, что что-то делаю не так, а именно не синхронизирую потоки.

С Java скорее на Вы, чем на ты. Подскажите, пожалуйста, как правильно передавать данные из private нитки в главный (ui) поток. Готов ответить на любые дополнительные вопросы.


Рекомендую почитать книжку блоха про многопоточность.

Вообще в жабе для синхронизации есть специальное слово syncrhonized, которое ставят перед именем метода...

BattleCoder ★★★★★
()
Ответ на: комментарий от BattleCoder

Вообще в жабе для синхронизации есть специальное слово syncrhonized, которое ставят перед именем метода...

Ага, я в курсе. Но ситуация на данный ммоент похожа на описанную в басне «Мартышка и очки»...

Bazarov
() автор топика
Ответ на: комментарий от Bazarov

Ну что тут непонятного? Оберните вызов:

onDataReceived( data, data.length );
во что-то вроде
onDataReceived( getData(), getLength() );
И создайте два метода
private syncrhonized byte[] getData() { бла-бла-бла} ;
private syncrhonized int getLength() { бла-бла-бла} ;

BattleCoder ★★★★★
()
Ответ на: комментарий от BattleCoder

Опечатался. правильно не synchronized, а synchronized. вроде так... ну сами уж там перепроверьте.

BattleCoder ★★★★★
()

Кстати, тогда глупый вопрос, а зачем вам передавать в параметры size, если его можно узнать из buffer, обратиться к buffer.size()? Лишних параметров лучше избегать. :) Можно внутри метода переприсвоить final int size = buffer.size()

BattleCoder ★★★★★
()
Ответ на: комментарий от BattleCoder

Если честно, я тоже задавался этим вопросом. Авторы android-serialport-api считают по-другому. Сделал под копирку.

Bazarov
() автор топика
Ответ на: комментарий от observer

Кратко идея: в родительском классе создаем экземпляр мютекса. Передаем мютекс дочернему классу. Когда родительский класс доходит до точки синхронизации он ждет (mutex.wait()), а когда дочерний доходит до точки синхронизации - обрабатывается оповещение (mutex.notify()).

observer ★★★
()

Подскажите, пожалуйста, как правильно передавать данные из private нитки в главный (ui) поток

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //здесь мы в ui потоке
            }
        });
anonymous
()

Друзья, спасибо Вам большое!

Дьявол скрылся совершенно в другом месте. А именно в переводе массива байтов в целое число:

Было:

int resource;
resource   = ( (int)buffer[0] ) * 65536;
resource  += ( (int)buffer[1] ) * 256;
resource  += ( (int)buffer[2] ) * 1;

Надо:

int resource;
resource   = ( (int)buffer[0] & 0xff ) << 16;
resource  += ( (int)buffer[1] & 0xff ) << 8;
resource  += ( (int)buffer[2] & 0xff );

Синхронизация изначально была в порядке. Теперь, думаю, понятно упоминание про мартышку и очки :)

Bazarov
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.