2016-04-17 3 views
2

Я пытаюсь сделать поток обновлений на HandlerThread, используя следующий класс, но у меня есть несколько вопросов о том, как работает захват переменных в Java.Как захватить область охвата в Runnable

[1]ret снят с ограничения по объему по ссылке?

[2] ли this относятся к Runnable, или он захвачен от объема вмещающей?

[бонус]StartStream должны размещать Runnable на поток обработчика, и только вернуться, когда Runnable завершена. Будет ли код ниже работать должным образом?

public class Stream extends HandlerThread { 
    Handler handler = null; 

    Stream() { 
     super("Stream"); 
     handler = new Handler(getLooper()); 
     start(); 
    } 

    private int _startStream() { // Start some repeating update 
     return 1; 
    } 

    public int StartStream() { 
     int ret = -1; 

     handler.post(new Runnable(){ 
      @Override public void run() { 
       synchronized(this) { 
        ret = _startStream(); // [1] 
        this.notify();   // [2] 
       } 
      } 
     }); 

     synchronized(this) { 
      while(ret == -1) { 
       try { 
        this.wait(); 
       } 
       catch (InterruptedException e){} 
      } 
     } 

     return ret; 
    } 
} 
+2

Почему вы расширяете 'HandlerThread'? – pskink

+0

@pskink Почему бы и нет? – bitwise

+0

, потому что 'HandlerThread' предназначен для непосредственного использования – pskink

ответ

3

Внутренние классы имеют неявные ссылки на внешний класс.

Чтобы использовать ret в анонимном внутреннем классе, он должен быть окончательным. Причина, по которой локальные переменные не могут ссылаться как неконфиденциальные, заключается в том, что экземпляр локального класса может оставаться в памяти после возвращения метода. Это также зависит от java version. Тем не менее он должен быть «эффективно окончательным» или переместить его в переменную-член.

this относится к Runnable, вы должны использовать Stream.this для его включения.

+0

Я не понимаю, что вы имеете в виду «ret». Мне нужно установить флаг переменной/в область действия Runnable. Как достигается достижение «ret» final/read-only? – bitwise

+0

Вы имеете в виду, что локальные переменные автоматически фиксируются как окончательные как механизм безопасности, так как они могут выйти из сферы действия? – bitwise

+0

Вы должны добавить final для удовлетворения компилятора –

1

ret является локальной переменной и, следовательно, должно быть эффективно окончательным. Это означает, что компилятор жалуется, если ret присваивается другому значению после его инициализации. Таким образом, [1] приводит к ошибке компилятора.

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

Для получения дополнительной информации о переменном захвате от метода ограждающего:

this действительно относится к экземпляру Runnable. Однако вы можете использовать Stream.this, чтобы обратиться к прилагаемому экземпляру Stream.

Смежные вопросы