我偶然发现了代码中的一个现象,可以归结为:
我有一个OSGi声明式服务,提供了如下配置的两个服务接口:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="dispose" enabled="true" name="redacted.redactedstore">
<implementation class="redacted.RedactedStore"/>
<service>
<provide interface="redacted.IRedactedStore"/>
<provide interface="redacted.IRedactedStoreControl"/>
</service>
</scr:component>
在我的代码中,我有两个不同的线程,它们都通过不同的接口打开一个ServiceTracker
来获取服务实例:
tracker = new ServiceTracker<>(getBundle().getBundleContext(), <serviceClass>.class, null);
tracker.open();
tracker.waitForService(1000l);
因此,一个线程使用IRedactedStore
作为服务类,另一个线程使用IRedactedStoreControl
作为服务接口。
因此似乎发生的事情是,当两个线程在正确的时间并行运行时,Equinox SCR不会实例化一个(如我期望的那样),而是实例化组件实现类的两个实例。
此行为正确吗?还是OSGi的Equinox实现中的错误?
如果行为正确,我可以在代码中做一些事情来通过另一种方式配置服务来防止这种情况吗? (当然,我可以重组服务,以便它仅提供一个接口,或者可以同步服务跟踪器...)
答案 0 :(得分:5)
对于非原型范围组件,我希望仅创建一次。 参见declarative services spec。
如果仅当服务跟踪程序并行运行时才发生此问题,那么我怀疑这可能是Equinox scr中的并发问题。