java - bundle 字段上的引用注释

标签 java multithreading osgi declarative-services

我正在使用 OSGi 开发应用程序。看里面 OSGi compendium 6.0 (section 112.8.1) 我遇到过声明式服务;特别是我看了以下段落:

For a field, the defaults for the Reference annotation are:

  • The name of the bind method or field is used for the name of the reference.
  • 1:1 cardinality if the field is not a collection. 0..n cardinality if the field is a collection.
  • Static reluctant policy if the field is not declared volatile. Dynamic reluctant policy if the field is declared volatile
  • The requested service is the type of the field.

For example:

@Reference
volatile Collection<LogService> log;

现在,我从 Neil Bartlett's OSGi in practice (section 11.10.2) 读取Reference annotationbindunbind 方法的同步和并发有点棘手(尤其是在动态策略场景中)。特别是,通过注释引用服务的线程安全示例可能是:

@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),我如何实现线程安全?仅通过将引用定义为“易变”(如纲要建议的那样)?或者有一些棘手的部分会在应用程序中产生问题?

谢谢你的回复

最佳答案

当您在字段上使用动态策略引用时,该字段必须是可变的。在您的示例中,每次 LogServices 集更改时,都会将一个新集合注入(inject)该字段。所以这将是安全的,因为如果您的代码迭代旧集合,则旧集合不会改变。当您的代码返回到日志字段时,它将看到新的集合。

因此,您需要做的就是将字段声明为 volatile,并且不要将字段值存储在其他地方,因为只要绑定(bind)服务集发生变化,该字段就会更新为新集合。

关于java - bundle 字段上的引用注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40175076/

相关文章:

java - 需要创建ExecutorService的对象

c++ - 链接基于 Qt 的应用程序时出错

c++ - openMP C++ 简单并行区域 - 输出不一致

java - 多个 OSGi 服务

java - 围绕变量而不是类或方法进行同步

java - 尝试使用 Java 客户端库将大文本文件插入 Google 云端硬盘时出现超时异常

java - Maven 不会从谷歌存储库下载 jar

java - 将 EAR 模块转换为 OSGI 包的正确方法

java - OSGi/BND : Different requirements depending on OS

java - 如何通过Java应用程序访问ServiceDesk Plus API : Error Authorizing Technician Key