单身人士并不是一个单身人士

我有这样的情况,我在运行嵌入式服务器的代码和我的Web应用程序之间共享单例。 我有类和部署工具的战争。 当我printf实例时,我看到:

abc.Abc@173a10f abc.Abc@105738 

所以这不是单身人士。 这是怎么回事?


我的服务器Jetty启动代码:

 public static void main(String[] args) throws Exception { System.out.println(MySingleton.getInstance()); // start Jetty here and deploy war with WebAppContext() } 

我的ServletContextListener端代码:

 public class AppServletContextListener implements ServletContextListener{ @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println(MySingleton.getInstance()); } } 

我的单身人士:

 public class MySingleton { private static MySingleton INSTANCE = new MySingleton(); private MySingleton () {} public static MySingleton getInstance() { return INSTANCE; } } 

我在构造函数中强制exception。 看起来我有两个不同。

 java.lang.Exception at api.MySingleton.(MySingleton.java:33) at api.MySingleton.(MySingleton.java:22) at my.project.StartJetty.main(StartJetty.java:41) java.lang.Exception at api.MySingleton.(MySingleton.java:33) at api.MySingleton.(MySingleton.java:22) at api.AppServletContextListener.contextInitialized(AppServletContextListener.java:25) at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:640) at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:229) at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1208) at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:586) at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:449) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58) at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58) at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89) at org.eclipse.jetty.server.Server.doStart(Server.java:258) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58) at my.project.StartJetty.main(StartJetty.java:66) 

看看一些Jetty文档 。 您可以使用类加载配置。

如果设置为true,则Jetty使用普通的JavaSE类加载优先级,并优先使用父/系统类加载器。 这避免了webapp中类的多个版本的问题,但是父/系统加载器提供的版本必须是以这种方式配置的所有Web应用程序的正确版本。

这正是您所描述的情况。 一个MySingleton实例由主Java程序加载,另一个由Jetty的类加载器加载。

在构造函数中打印堆栈跟踪应该为您提供所需的信息,以找出实例化的位置和顺序。 Singleton模式是一件危险的事情,通常以不同的方式做得更好。

您的ServletContextListener和主类由不同的类加载器加载。 每当加载一个类时,它的静态块都将被执行。 所以你会得到两个实例……

如果要确保同一个类加载器加载单例,则必须自己指定类加载器。

查看此链接了解更多详情http://www.javaworld.com/article/2073352/core-java/simply-singleton.html?page=2

    Interesting Posts