[英]How to resolve Java issue with multiple threads when executing with a runnable jar file?
I have developed a Java Swing application, which uses the SwingWorker class to perform some long running tasks. 我开发了一个Java Swing应用程序,它使用SwingWorker类来执行一些长时间运行的任务。 When the application is run from the IDE (Netbeans), I can start multiple long running tasks simultaneously without any problem.
当应用程序从IDE(Netbeans)运行时,我可以同时启动多个长时间运行的任务而没有任何问题。
I created a runnable jar file for the application, in order to be able to run it from outside the IDE. 我为应用程序创建了一个可运行的jar文件,以便能够从IDE外部运行它。 The application when run from this jar file works well with the only exception that it doesn't allow me to start 2 long running tasks simultaneously.
从这个jar文件运行时的应用程序运行良好,唯一的例外是它不允许我同时启动2个长时间运行的任务。 The tasks just run one after the other.
任务只是一个接一个地运行。
I managed to create a very simple program which demonstrates this problem. 我设法创建了一个非常简单的程序来演示这个问题。 link The program uses a swingworker which just loops from 1 till 100 and writes the number to the console.
link该程序使用一个swingworker,它从1到100循环,并将数字写入控制台。 The two buttons initiate two threads which do the same thing.
这两个按钮启动两个执行相同操作的线程。 If i run this program on netbeans, the threads interleave, while if i create a jar file and run the application from the jar file, the threads do not interleave, but run one after the other.
如果我在netbeans上运行这个程序,线程交错,而如果我创建一个jar文件并从jar文件运行应用程序,线程不会交错,而是一个接一个地运行。
It seems as if the jvm does not allow more than one thread to run at any one time, when the application is run from the jar file. 当从jar文件运行应用程序时,似乎jvm在任何时候都不允许运行多个线程。
Here is the code for those of you having problems with the link 以下是您遇到链接问题的代码
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");
}
}
}
Thanks in advance, Peter Bartolo 在此先感谢Peter Bartolo
Apparently, SwingWorker
s by default all execute on the same background thread in JDK 1.6 显然,
SwingWorker
默认情况下都在JDK 1.6中的相同后台线程上执行
Add these 添加这些
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
At the top of your Main()
add this 在
Main()
的顶部添加此项
final Executor executor = Executors.newCachedThreadPool();
And in your actionPerformed
s, execute your SwingWorker
s like this 在你的
actionPerformed
s中,像这样执行你的SwingWorker
executor.execute(new Main.MyTask("First"));
This will execute each SwingWorker on a separate thread in a Thread pool. 这将在线程池中的单独线程上执行每个SwingWorker。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.