我的问题是在主类中我有一些osgi引用,在调用类时工作得很好。但之后所有引用都变为null。当我关闭主窗口并调用shutdown方法时,hubService引用返回null。我在这做错了什么?
private void shutdown() {
if(hubService == null) {
throw new NullPointerException();
}
hubService.shutdownHub(); // why is hubService null?
}
// bind hub service
public synchronized void setHubService(IHubService service) {
hubService = service;
try {
hubService.startHub(PORT, authenticationHandler);
} catch (Exception e) {
JOptionPane.showMessageDialog(mainFrame, e.toString(), "Server", JOptionPane.ERROR_MESSAGE);
System.exit(0);
}
}
// remove hub service
public synchronized void unsetHubService(IHubService service) {
hubService.shutdownHub();
hubService = null;
}
答案 0 :(得分:0)
如果一个字段可以被多个线程读取和写入,则必须保护读取和写入的访问权限。您的第一个方法shutdown不保护hubService的读取,以便hubService的值可以在第一次读取和第二次读取之间更改。您不显示hubService字段的声明。您可以将其设置为volatile或仅在同步时读取(在写入字段时用于同步的同一对象)。然后您的关闭实现可能如下所示:
private volatile IHubService hubService;
private void shutdown() {
IHubService service = hubService; // make a copy of the field in a local variable
if (service != null) // use local var from now on since the field could have changed
service.shutdownHub();
}
答案 1 :(得分:0)
我假设您的关机方法是DS停用方法?如果是这样,为什么在关闭方法中也会关闭unset方法?
整体而言,设计似乎不太合理。 IHubService用作工厂,应该返回一些在deactivate方法中关闭的对象。您使IHubService有效地成为单身人士。因为它必须来自另一个束,它应该自己处理它的生命周期。
由于您也不使用注释,因此不清楚您的set / unset方法是静态/动态和/或单个/多个。以下代码不应该有您的问题(带有bnd注释的例程代码):
@Component public class MyImpl {
IHubService hub;
@Activate
void activate() {
hubService.startHub(PORT, authenticationHandler);
}
@DeActivate
void deactivate() {
hubService.shutdown();
}
@Reference
void setHub(IHubService hub) { this.hub = hub; }
}