OSGI ServiceTracker и безопасность потоков - PullRequest
1 голос
/ 11 сентября 2011

ServiceTracker определен как потокобезопасный класс в спецификации OSGI 4.2

Использование этого класса довольно простое.

Большинство примеров использования ServiceTracker я мог найти нав интернете показан фрагмент кода, подобный следующему:

ServiceInterface serviceObj = (ServiceInterface) serviceTracker.get();
if(serviceObj != null) {
  // ...
  // do smth with the serviceObject
  // ...
}

Теперь мой вопрос: как только объект реализации службы получен из serviceTracker, нет гарантии, что он будет доступен (не будет удален) сразу после нулевой проверки.

Другими словами, даже в цикле if объект службы (serviceObj) может очень быстро внезапно обнулиться (если соответствующая служба не зарегистрирована)

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

ServiceInterface serviceObj = (ServiceInterface) serviceTracker.get();
if(serviceObj != null) {
 try {
  // ...
  // do smth with the serviceObject
  // ...
 } catch(Throwable th) {
  // a null-pointer exception may have occurred here!!
 }
}

Несмотря на это, в блогах также нет примеров (http://developers -blog.org / blog / default / 2010/03 /31 / OSGI-Tutorial-How-to-use-Service-Tracker-to-get-Services ) или книги (Osgi In Action) говорят об этом требовании ...

Я прав?Я что-то упустил?

1 Ответ

2 голосов
/ 11 сентября 2011

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

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

В некотором смысле это является основой дебатов между проверенными и непроверенными исключениями.

Обратите внимание на одно небольшое исправление:Ваша ссылочная переменная serviceObj не может стать null после нулевой проверки, поскольку она является локальной переменной, и другие потоки никогда не смогут изменить значение ваших локальных переменных.Однако, как вы поняли, сервисная ссылка может перестать работать или перестать работать.Шансы на это очень малы, хотя вы только что получили ссылку с трекера.

...