2010-05-24 15 views
7

Tôi đã phát triển một ứng dụng Java Swing, sử dụng lớp SwingWorker để thực hiện một số tác vụ chạy dài. Khi ứng dụng được chạy từ IDE (Netbeans), tôi có thể bắt đầu nhiều tác vụ chạy đồng thời lâu mà không gặp bất kỳ vấn đề nào.Làm thế nào để giải quyết vấn đề Java với nhiều chủ đề khi thực hiện với một tệp jar chạy được?

Tôi đã tạo một tệp jar có thể chạy được cho ứng dụng, để có thể chạy nó từ bên ngoài IDE. Ứng dụng khi chạy từ tệp jar này hoạt động tốt với ngoại lệ duy nhất là nó không cho phép tôi bắt đầu 2 tác vụ chạy dài cùng một lúc. Các nhiệm vụ chỉ chạy cái này sau cái kia.

Tôi đã quản lý để tạo một chương trình rất đơn giản thể hiện vấn đề này. link Chương trình sử dụng một swingworker mà chỉ vòng từ 1 đến 100 và ghi số vào bàn điều khiển. Hai nút bắt đầu hai luồng làm cùng một điều. Nếu tôi chạy chương trình này trên netbeans, các chủ đề xen kẽ, trong khi nếu tôi tạo ra một tập tin jar và chạy các ứng dụng từ tập tin jar, các chủ đề không xen kẽ, nhưng chạy cái khác.

Dường như là jvm không cho phép nhiều hơn một luồng chạy cùng một lúc, khi ứng dụng được chạy từ tệp jar.

Đây là mã cho những người bạn gặp vấn đề với các liên kết

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"); 
     } 

    } 

} 

Cảm ơn trước, Peter Bartolo

+1

Hiển thị cho chúng tôi một số mã có thể giúp chúng tôi giúp bạn – karoberts

+0

vâng tôi đã đăng một chương trình rất đơn giản thể hiện sự cố –

+0

Bất kỳ ai quản lý để sao chép sự cố trên máy của mình? –

Trả lời

4

Rõ ràng, SwingWorker s theo mặc định tất cả các thực thi trên thread nền cùng trong JDK 1,6

Thêm những

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

Ở phía trên của Main() bạn thêm này

final Executor executor = Executors.newCachedThreadPool(); 

Và trong actionPerformed của bạn, hãy thực hiện SwingWorker của bạn như thế này

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

này sẽ thực hiện mỗi SwingWorker trên một sợi riêng biệt trong một hồ bơi Ðề tài.

+0

Một nghìn Cảm ơn m8, nó hoạt động ngay bây giờ :) –

+0

Vui vì tôi có thể giúp – karoberts

Các vấn đề liên quan