2010-05-24 33 views
7

我開發了一個Java Swing應用程序,它使用SwingWorker類來執行一些長時間運行的任務。當應用程序從IDE(Netbeans)運行時,我可以同時啓動多個長時間運行的任務,而沒有任何問題。如何在使用可運行jar文件執行時解決多線程的Java問題?

我爲應用程序創建了一個可運行jar文件,以便能夠從IDE之外運行它。從這個jar文件運行的應用程序運行良好,唯一的例外是它不允許我同時啓動2個長時間運行的任務。這些任務一個接一個地運行。

我設法創建了一個非常簡單的程序來演示這個問題。 link 該程序使用一個只從1到100循環的擺動工具,並將編號寫入控制檯。兩個按鈕啓動兩個執行相同操作的線程。如果我在netbeans上運行這個程序,線程會交錯,而如果我創建一個jar文件並從jar文件運行應用程序,線程不會交錯,但是會一個接一個地運行。

看起來好像jvm不允許多個線程在任何時候運行,當應用程序從jar文件運行時。

這裏是你所具有的鏈路問題提前

package testingjarpath; 

import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.List; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 

public class Main extends JFrame { 
    private JButton btnTest; 
    private JButton btnTest2; 

    public Main() { 

     this.btnTest = new JButton("Test 1"); 
     this.btnTest.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       new Main.MyTask("First").execute(); 
      } 
     }); 

     this.btnTest2 = new JButton("Test 2"); 
     this.btnTest2.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       new Main.MyTask("Second").execute(); 
      } 
     }); 

     this.setLayout(new FlowLayout()); 
     this.add(this.btnTest); 
     this.add(this.btnTest2); 
     this.setSize(new Dimension(400, 400)); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new Main(); 
      } 
     }); 
    } 

    public class MyTask extends SwingWorker<Void, Integer> { 
     private String str; 

     public MyTask(String str) { 
      this.str = str; 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for (int i = 0; i < 100; i++) { 
       Thread.sleep(100); 
       publish(i); 
      } 
      return null; 
     } 

     protected void process(List<Integer> progress) { 
      System.out.println(str + " " + progress.get(progress.size() - 1)); 
     } 

     @Override 
     protected void done() { 
      System.out.println(str + " is ready"); 
     } 

    } 

} 

感謝的代碼, 彼得巴託羅

+1

向我們展示一些代碼可能會幫助我們幫助您 – karoberts 2010-05-24 02:21:55

+0

是的,我發佈了一個非常簡單的程序,它演示了這個問題 – 2010-05-24 02:34:22

+0

任何人都設法在他的機器上覆制問題? – 2010-05-24 03:06:06

回答

4

顯然,SwingWorker S按默認情況下所有執行於JDK同一後臺線程1.6

添加這些

import java.util.concurrent.Executor; 
import java.util.concurrent.Executors; 

在你Main()頂部添加此

final Executor executor = Executors.newCachedThreadPool(); 

而在你actionPerformed S,執行你的SwingWorker就像這個

executor.execute(new Main.MyTask("First")); 

這將執行在一個線程池一個獨立的線程每個SwingWorker的。

+0

千謝謝m8,它現在的作品:) – 2010-05-24 03:48:31

+0

很高興我能幫到你 – karoberts 2010-05-24 04:02:15

相關問題