2016-10-21 6 views
1

Я разрабатываю приложение с OSGi. Глядя внутрь OSGi compendium 6.0 (section 112.8.1) Я столкнулся с декларативным сервисом; в частности, я смотрел следующий пункт:Ссылка аннотации на поле пучка

Для поля, значение по умолчанию для эталонной аннотации является:

  • Имени метода связывания или поле используются для названия ссылки.
  • 1: 1 мощность, если поле не является коллекцией. 0..n, если поле является коллекцией.
  • Статическая политика неохотой, если поле не объявлено изменчивым. Динамическая политика неохотой, если поле объявлено изменчивым
  • Запрошенная услуга - это тип поля.

Например:

@Reference 
volatile Collection<LogService> log; 

Теперь, я читать из Neil Bartlett's OSGi in practice (section 11.10.2), что синхронизация и параллелизма связывают и UNBIND методов Reference annotation немного сложно (особенно в динамических scnearios политики) , В частности, потокобезопасный пример ведения службы через аннотацию может быть:

@Component(provide = MailboxListener.class, properties = { "service.ranking = 10"}) 
public class LogMailboxListener implements MailboxListener { 
    private final AtomicReference<Log> logRef = newAtomicReference <Log>() ; 

    public void messagesArrived (String mboxName, Mailbox mbox, long [ ] ids) { 
     Log log = logRef.get(); 
     if (log != null) 
      log.log(Log.INFO, ids.length + "message(s) arrived in mailbox " + mboxName, null); 
     else 
      System.err.println("No log available!"); 
    } 

    @Reference(service = Log.class, dynamic = true, optional = true) 
    public void setLog(Log log) { 
     logRef.set(log); 
    } 

    public void unsetLog(Log log) { 
     logRef.compareAndSet(log, null); 
    } 
} 

Я думаю, что я понял из книги, почему динамическая политика нуждается в этом КОРРЕКТИРОВКЕ из сценария в многопоточном. Мой вопрос: , если эталонная аннотация была на поле (декларативное обслуживание 1.3), как я мог бы обеспечить безопасность потока? Только определив ссылку как «изменчивую» (как подсказывает компендиум)? Или есть какая-то сложная часть, которая создаст проблемы в приложении?

Спасибо за любого рода ответ

ответ

2

При использовании динамической ссылки политики на поле, поле должно быть неустойчивыми. В вашем примере каждый раз, когда набор LogServices изменяется, в поле вводится новая коллекция. Таким образом, это будет безопасно, так как если ваш код выполняет итерацию по старой коллекции, старая коллекция не изменяется. Когда код вернется в поле журнала, он увидит новую коллекцию.

Итак, все, что вам нужно сделать, это объявить поле volatile и не сохранять значение поля где-то еще, так как поле будет обновляться до новой коллекции всякий раз, когда изменяется набор связанных служб.

+0

Итак, чтобы использовать поле-аннотированную привязку связки, мне нужно, когда мне нужно использовать ссылку, использовать само поле (а не локальную копию, такую ​​как 'LogService a = this.log')? Позвольте мне привести пример (для semplicity я буду использовать простой 'LogService' вместо их набора):' public void foo() {if (this.log! = Null) {this.log.log ("foo start «); // делать другой код} 'Это поточно-безопасный с полем' log', просто установленным на volatile? Или мне нужны дальнейшие операции? – Koldar

+0

Когда вам нужно использовать службу logservice, скопируйте ее в локальный var из поля, используйте локальный var, а затем пусть локальный var выходит из области видимости. Моя задача состояла в том, чтобы не копировать его из поля в другое место, которое удерживается в течение длительного времени (например, другой объект). –

+0

@BJHargave Ах, ладно, теперь я понимаю! Я прочитал ту же самую процедуру, которую вы только что написали в OSGi Нейла на практике, но из вашего комментария я ошибочно думал, что вы предложили избегать использования локальной переменной. Теперь все прекрасно!Я боялся, что ссылки на потокобезопасные службы были разными, используя аннотированное поле, но, видимо, все намного проще! Я даже не нуждаюсь в AtomicReference или проверяет 'null' внутри метода unbind. Похоже, что современные ссылки OSGi должны использовать как можно больше аннотированную версию DS, а не метод bind/unbind, правильно? – Koldar