К какому потоку относится переменная? - PullRequest
0 голосов
/ 09 октября 2011

У меня есть некоторый код, подобный этому:

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        Looper.prepare();

        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                  // process incoming messages here
            }
        };

        Looper.loop();
    }
}

Я хочу знать, к какому потоку принадлежит mHandler?

Добавить: Отличается ли я, если я объявляю (или инстанцирую его) в другой теме.

Ответы [ 5 ]

4 голосов
/ 09 октября 2011

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

Суть в том, что каждый объект, созданный с помощью оператора new, помещается вкуча, которая разделяется между всеми потоками.Другие потоки могут получить доступ к ссылке на объект, например, если она не инкапсулирована, как в вашем примере, или преднамеренно предоставлена.

С технической точки зрения - в Java любой объект не принадлежит ни одному другому - все ссылки на данный объект равны,И когда последняя ссылка на объект (огромное упрощение) исчезает, это сборщик мусора.Так что можно сказать: последняя ссылка владеет объектом.

1 голос
/ 09 октября 2011

Темы могут получить доступ ко всем полям.Только локальные переменные существуют только в одном потоке.

Если вы хотите получить доступ к потоку в блоке out, который вы можете использовать.LooperThread.this

0 голосов
/ 09 октября 2011

Если вы спрашиваете: «Из каких потоков безопасно получить доступ / изменить переменную mHandle?», То сейчас ваш код не блокирует присвоение

mhandle = ...

так что было бы безопасно получить доступ к нему из потока петлителя.Так что, если у вас есть другой кусок кода в другом потоке, проверяющий

if (looperThread.mhandle == null) {
}

, это не будет поточно-ориентированным.Вам придется заблокировать как присвоение, так и доступ

synchronized (this) {
    mhandle = ...
}
....
synchronized (looperThread) {
    if (looperThread.mHandle == null) {
    }
}

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

Просто помните, что переменная на самом деле не принадлежит потоку - к ней можно получить доступ из любого потока.На самом деле вопрос в том, когда безопасно получить к нему доступ из каких потоков?

0 голосов
/ 09 октября 2011

попробуйте использовать это в вашем методе handleMessage

Thread.currentThread().getName()
0 голосов
/ 09 октября 2011

Поскольку Handler является внутренним классом, он может обращаться к внешнему классу, используя следующий синтаксис:

        public void handleMessage(Message msg) {
            // process incoming messages here
            Thread t = LooperThread.this;
        }

Оттуда вы должны знать, что делать.

Обратите внимание:Экземпляр Thread является объектом.Но поток , в котором выполняется код, - это совсем другое.Не путайте представителя Thread с фактическим (ресурс ЦП).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...