簡體   English   中英

線程無法在Swing應用程序中啟動

[英]Thread does not start in a Swing application

我正在研究一個相對簡單的數據庫管理器,它以一種特定的方式接收大量文件,解析和編目信息。 為此,我還在Swing中編寫了一個簡單的GUI。 為了加快進程,我想對執行的可並行化部分實現多線程,以加速程序。

下面的代碼位於一個名為FDBCreatePanel的類中,這是一個自定義JPanel ,位於FDBManagerFrame ,可以容納main方法。

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 看起來好像我的代碼完全在單個線程上執行,忽略了新線程的啟動。 我是否遺漏了線程和Swing方面的內容?

正如Jon指出的那樣,你想調用start()方法來實際生成一個新的Thread,它將調用你的內聯Runnable的run方法。 如果你只是調用run,就像你調用任何其他方法一樣,它將在同一個Thread中執行。

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

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

您在ParserType1.init()新創建的Thread對象上調用run() 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)是final,而不是實現Runnable ,並強制您在構造時提供Runnable 現在改變已經太晚了,不幸的是:(

基本上,你永遠不應該在Thread上調用run() 至少,我記不起上次我看到它沒有它是一個bug。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM