2014-02-18 30 views
0

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

下面的代码位于一个名为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

你的'ParserType1.init'方法不会启动一个新的线程,当我怀疑你想调用'start'时,它调用'Thread'对象的'run' ... –

+0

@JonSkeet很好的捕获...虽然我不得不问为什么'run()'和'start()'?我的意思是有什么理由为什么会调用'run()'而不是'start()' – posdef

+1

做过线程的人犯了这个错误。;) – jeremyjjbrown

回答

1

你在ParserType1.init()调用新创建Thread对象run()。这不会启动新线程 - 它只是在现有线程中执行线程的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。这是为时已晚,现在来改变,遗憾的是:(

基本上,你应该永远Thread调用run()。至少,我不记得我最后一次看到,如果没有它是一个错误。

+0

有趣的是,我认为这肯定是关键问题,但我现在正在重新运行一个测试,并且即使在't.start()'之后,“t1-parser-thread”也是无处可见的......特殊 – posdef

+0

@posdef:也许它开始,但很快完成? –