Re[2]: Проблема с завершением и запуском потока по новой
От: s3dworld Россия  
Дата: 08.10.12 14:31
Оценка:
А вот на счёт volatile. Сама по себе то она просто указывает не лесть в кэш, а значение читать и записывать на прямую в память. Возможно для boolean типа это будет и в самый раз (зависит от того, может ли поток остановиться на половине считывания этого значения, но видимо один байт (если в ней один байт) он будет читать за раз). А как лучше поступить, если хочу чтобы у меня не было путаницы в доступе с другими объектами. Сейчас опишу что я хочу...

У меня есть два потока:

1. Поток Activity
2. Поток логики

(1) вызывается сам по себе при наступлении каких-то событий:

— Activity перекрыто, возрождено;
— на экране пальцем что-то сделали;
— нажали кнопку

(2) работает пока Activity активно. И его задача — это обновление состояния игры и вывод его на экран. А состояние может обновляться несколькими способами:

— с течением времени;
— в результате произошедших событий от Activity

С течением времени — это очень просто. А что касается другого способа, то тут давайте рассмотрим. Пока Activity активно, у меня вечно крутится цикл из обновления состояния и вывод его на экран. По сути это работает параллельно (особенно если в устройстве несколько ядер). Как только я тыкнул пальцем на экран, у меня код начал выполняться не потоком обновления состояния (тот что у меня был GameThread), а потоком Activity. И в результате координаты куда тыкнули мне должны попасть как-то и в поток логики. В общем тут получается что такое нажатие может чем-то навредить другому потоку, так как он постоянно читает/записывает какие-то данные, а тут ещё эти же данные другой поток захочет изменить. Ну и вполне понятно что тут нужна синхронизация.

Как я решил сделать, я последовал примеру из Win32 API — как там это работается с окнами (как окна получают сообщения и обрабатывают их). У меня есть класс InputManager, который выглядит следующим образом:

public final class InputManager
{
    private LinkedBlockingQueue<TouchEvent> qTouch;
    private LinkedBlockingQueue<KeyboardEvent> qKeyboards;

    public InputManager()
    {
        qTouch=new LinkedBlockingQueue<TouchEvent>();
        qKeyboards=new LinkedBlockingQueue<KeyboardEvent>();
    }

    public void pushTouch(MotionEvent _event)
    {
        try
        {
            qTouch.put(new TouchEvent(_event));
        }
        catch(InterruptedException _exception)
        {
        }
    }

    public void pushKeyboard(KeyEvent _event)
    {
        try
        {
            qKeyboards.put(new KeyboardEvent(_event));
        }
        catch(InterruptedException _exception)
        {
        }
    }

    public TouchEvent popTouch()
    {
        return qTouch.poll();
    }

    public KeyboardEvent popKeyboard()
    {
        return qKeyboards.poll();
    }

}


Поток Activity вносит события, а поток обновления игры забирает их. Вообще так то всё работает. И проблему в первом посте я решил за счёт разъединения GameThread на GameThread и Game (первый каждый раз пересоздаётся). Но что касается этого сообщения, то я беспокоюсь что такой способ может быть достаточно медленным.

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