yhs0092 opened a new issue, #3928:
URL: https://github.com/apache/servicecomb-java-chassis/issues/3928

   ## 版本
   
   Java-Chassis 2.8.9
   
   ## 问题原理
   
   SCBEngine是单例的, 单例对象由其属性`private static volatile SCBEngine INSTANCE`引用, 
这个属性在`SCBEngine`构造方法中赋值初始化. 代码如下:
   ```java
     protected SCBEngine() {
       eventBus = EventManager.getEventBus();
   
       eventBus.register(this);
   
       INSTANCE = this;
   
       producerProviderManager = new ProducerProviderManager(this);
       serviceRegistryListener = new ServiceRegistryListener(this);
     }
   ```
   
   但由于执行`INSTANCE = this;`这一行时, `producerProviderManager` 和 
`serviceRegistryListener` 属性还没有完成初始化, 则其他线程可能在`SCBEngine()`构造方法还没跑完时就拿到单例对象, 
此时若调用`getProducerProviderManager()`方法就会拿到`null`返回值.
   
   ## 问题场景举例
   
   如果业务在一个后台任务线程中提前执行一次CSE调用, 而在`main`启动线程中正在走启动流程. 
则可能后台任务线程里先触发SCBEngine对象构造方法. 当后台任务线程刚好跑到`SCBEngine()`的`INSTANCE = this;`这一行时, 
`main`线程正走到`SCBApplicationListener#onApplicationEvent`方法执行85行的`scbEngine.getProducerProviderManager().getProducerProviderList()`,
 此时业务就会在Java-Chassis启动日志里看到一个空指针异常.
   
   ## 期望
   
   固然问题解决的根本方法是业务调整后台任务的执行时机, 但这里`SCBEngine`的空指针异常会非常令人费解, 而且比较耽误问题分析定位的时间. 
所以建议这个地方最好是优化一下单例的写法, 确保`SCBEngine.getInstance()`返回的单例对象是初始化完成的.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to