奇怪的Java错误/错误:堆栈溢出,空指针和双重锁定

Pur*_*ret 5 java singleton

我真的不知道如何正确解释这个错误...

它是在我将此方法添加到我的控制器类时开始的:

public void loadPlayerComboBox() {
    try{
        final PreparedStatement collectPlayerNames = 
                ConnectionManager.getConnection().prepareStatement("SELECT "+PLAYER_NAME+"  FROM PLAYERS");
        final ResultSet playerNameResults = collectPlayerNames.executeQuery();
        while(playerNameResults.next()){
            IViewManager.Util.getInstance().getMyContainerPane().getMyPlayerManagerPane().getPlayerNameList()
            .add(playerNameResults.getString(PLAYER_NAME));
        }
    }catch(final SQLException e){
        System.out.println("SQLException. Reason: " + e.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

而且我已经确认没有这个方法(在课程启动时由类调用)我没有错误.

我的错误?当我从eclipse运行时,程序开始加载框架的顶栏出现,但实际内容却没有.

在此输入图像描述

除此之外还有一个奇怪的空箱,我认为这是由多个进程启动引起的.

这个,我相信是由堆栈溢出引起的,因为我的getInstance()方法以递归方式相互调用.由于某种原因,我无法恢复堆栈跟踪,此时调试屏幕只是空白.我检查了我的.log,它没有与该时间戳相对应的错误.我不知道他们怎么可以互相打电话.这是ViewManager方法:

static class Util {
    static private IViewManager viewManager = null;
    static public synchronized IViewManager getInstance() {
            if (viewManager == null) {
                    viewManager = new ViewManager();
            }
            return viewManager;
    }
}
Run Code Online (Sandbox Code Playgroud)

和构造函数:

public ViewManager(){
    super("Tony Larp DB Manager");
    this.setVisible(true);
    this.setDefaultCloseOperation(3);
    myContainerPane = new ContainerPane();
    myContentMenu = new ContentMenu();
    IController.Util.getInstance();
    IPlayerCharacterManager.Util.getInstance();
    this.setJMenuBar(myContentMenu);
    this.getContentPane().add(myContainerPane);
    this.pack();        
}
Run Code Online (Sandbox Code Playgroud)

IController.Util.getInstance()方法是相同的,除了它调用的类和对象的名称不同.双重检查锁定只会导致我的启动程序中的第一个IViewManager.getInstance()实例返回一个空指针,这是在synchronized块的开头.

为了澄清,程序IViewManager.Util.getInstance()在启动器IController.Util.getInstance()中第一次调用,然后它在上面的构造函数中第一次调用.之后,对它的所有调用应该只返回实例.

什么会导致这种错误?我怎么能开始修复它?

Pur*_*ret 0

这种行为表明你已经陷入了某种无限循环。有些地方你交叉了线程(线程中的一个方法调用另一个方法中的方法,后者调用第一个方法)。

两者都没有完成构建,因此您的单例没有实例可以调用。相反,他们不断尝试无限地实例化彼此。返回并重新考虑单例代码线程的独立程度。