[英]How to make multithreaded swing gui application start/stop thread with 2 buttons
[英]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.