Java全局异常处理程序中的可见性

时间:2014-10-16 15:13:22

标签: java exception-handling global visibility uncaughtexceptionhandler

我正在用Java编写一个程序,允许一个人将数据作为帮助台的工作输入到表单中。然后使用提交的表单创建一个helpRequest对象,该对象被输入到通用队列中以存储在二进制文件中。但是,项目的责任(这是一项学校作业)是使用例外使程序失败。该程序的一个具体规定是它必须通过在“正常”终止之前尝试保存当前的helpRequest队列来处理无法继续的任何情况。我已经在代码中设置了所有这些,但是当处理程序运行时(在我的测试中通过除零),程序一旦尝试使用helpQueue执行任何操作就会挂起。

我已经尝试查找Java全局变量和全局异常处理程序,但似乎没有解决使用来自另一个/抛出类的结构或变量的主题。

以下是处理程序的代码。我在投掷类HelpDeskForm中将helpQueue声明为public和static,NetBeans接受我在这里的所有代码。在使用队列之后发生诱导异常。

public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler {

    BinaryOutputFile emergencyOutput;

    public void uncaughtException(Thread t, Throwable e) {
        Frame f = new Frame();
        JOptionPane.showMessageDialog(f, "Program error.  Please select a file for queue output.");
        emergencyOutput = new BinaryOutputFile();
        while(!HelpDeskForm.helpQueue.isEmpty())
            emergencyOutput.writeObject(HelpDeskForm.helpQueue.remove());
        emergencyOutput.close();        
        System.exit(1);
    }

}

如果有人可以解释为什么helpQueue在这个异常处理程序中看起来实际上不可见/可用,或者我正在做的可怕的错误,我会很感激。

编辑:我不想让我的解释过于复杂,但这里是HelpDeskForm代码直到我的除零异常。

public class HelpDeskForm {

    BinaryDataFile input;
    BinaryOutputFile output; 
    CheckedForm c;
    helpRequest r;
    public static Queue<helpRequest> helpQueue;
    int inputSize;

    public HelpDeskForm() {

        GlobalExceptionHandler h = new GlobalExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(h);

        input = new BinaryDataFile();
        inputSize = input.readInt();
        for(int i = 0; i < inputSize; i++) {
            helpQueue.add((helpRequest)input.readObject());
        }
        input.close();

        int y = 0;
        int z = 2;
        z = z/y;
        ... // GUI code follows 
    }
}    

1 个答案:

答案 0 :(得分:0)

HelpDeskForm似乎缺乏正在使用的队列的初始化,因此NPE是不可避免的。尝试在声明中添加初始化:

public static Queue<helpRequest> helpQueue = new ArrayBlockingQueue<helpRequest>(100);

另外,对于发布的代码,将volatile关键字添加到队列声明中是合乎逻辑的:

public static volatile BlockingQueue<helpRequest> helpQueue;

public void createQueue() {
   // make sure createQueue() is called at the very beginning of your app,
   // somewhere in main()
   helpQueue = new ArrayBlockingQueue...
}

这样所有其他线程(如果有的话)都会看到对队列的正确引用,BlockingQueue的线程安全性可以保证其内容的正确可见性。