2

我正在用 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 
    }
}    
4

1 回答 1

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保证了其内容的正确可见性。

于 2014-10-16T21:31:44.407 回答