线程无法在Swing应用程序中启动

时间:2014-02-18 14:59:54

标签: java multithreading swing

我正在研究一个相对简单的数据库管理器,它以一种特定的方式接收大量文件,解析和编目信息。为此,我还在Swing中编写了一个简单的GUI。为了加快进程,我想对执行的可并行化部分实现多线程,以加快程序。

下面的代码位于一个名为FDBCreatePanel的类中,一个自定义JPanel,位于FDBManagerFrame中,可以容纳主方法。

private void dbCreateActionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dbCreateActionButtonActionPerformed

    jfc = new JFileChooser();               
    jfc.setVisible(true);
    jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    int returnVal = jfc.showSaveDialog(null);
    ((FDBManagerFrame) SwingUtilities.getRoot(this)).startProcessAnimation();

    if(returnVal == JFileChooser.APPROVE_OPTION) {
        new SwingWorker<Void,Void>(){
            @Override
            protected Void doInBackground() throws Exception {
                File dir = jfc.getSelectedFile();
                DbManager dbm = new DbManager(dir, dbNameField.getText());
                try{
                    dbm.doTimeConsumingStuff();

                } catch (SQLException e){
                    // errorhandling
                } 
            @Override
            protected void done() {
                ((FDBManagerFrame) SwingUtilities.getRoot(FDBCreatePanel.this)).endProcessAnimation();
            }
        }.execute();
    }       
}

DbManager类中耗时的方法导致{等级} ParserType1类中的以下代码:

private void init() {
    try {
        this.reader = new LineNumberReader(new FileReader(this.datfile));
        Thread t = new Thread(new Runnable(){
            @Override
            public void run() {
                Entry e;
                while((e = parseNextEntry()) != null)
                    queue.offer(e);
            }           
        }, "t1-parser-thread");
        t.run();
    } catch (FileNotFoundException e) {
        // error handling
    }
}

当我监视程序的执行时,我在JVisualVM中看不到任何t1-parser-thread(s)。看起来好像我的代码完全在单个线程上执行,忽略了新线程的启动。我是否遗漏了线程和Swing方面的内容?

2 个答案:

答案 0 :(得分:1)

正如Jon指出的那样,你想调用start()方法来实际生成一个新的Thread,它将调用你的内联Runnable的run方法。如果你只是调用run,就像你调用任何其他方法一样,它将在同一个Thread中执行。

}, "t1-parser-thread");
    t.start();

http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

答案 1 :(得分:1)

您正在run()中新创建的Thread对象上调用ParserType1.init()。这不会启动一个新线程 - 它只是在现有线程中执行线程的run()方法。您应该改为呼叫start()

从根本上说,我认为Thread完全实现Runnable是错误的 - “这是应该执行的代码”(Runnable)和“这是我将要执行它的方式“(Thread)不幸被弄糊涂了。 Thread 可以组成Runnable的事实使其更加糟糕。

Runnable runnable = new Runnable() { ... };
Thread thread = new Thread(runnable) {
    // Override run here...
};

除非被覆盖的run方法调用super.run(),否则将忽略传递给构造函数的Runnable。疯狂的事情。 Thread应该(IMO)是最终的,而不是实施Runnable,并且强制您在构建时提供Runnable。不幸的是,现在改变已经太晚了:(

基本上,您应该从不run()上呼叫Thread。至少,我记不起上次我看到它而不是它是一个错误。