如何使用可运行的jar文件执行多线程解决Java问题?

PB_*_*MLT 7 java multithreading

我开发了一个Java Swing应用程序,它使用SwingWorker类来执行一些长时间运行的任务.当应用程序从IDE(Netbeans)运行时,我可以同时启动多个长时间运行的任务而没有任何问题.

我为应用程序创建了一个可运行的jar文件,以便能够从IDE外部运行它.从这个jar文件运行时的应用程序运行良好,唯一的例外是它不允许我同时启动2个长时间运行的任务.任务只是一个接一个地运行.

我设法创建了一个非常简单的程序来演示这个问题.link 该程序使用一个swingworker,它从1到100循环,并将数字写入控制台.这两个按钮启动两个执行相同操作的线程.如果我在netbeans上运行这个程序,线程交错,而如果我创建一个jar文件并从jar文件运行应用程序,线程不会交错,而是一个接一个地运行.

当从jar文件运行应用程序时,似乎jvm在任何时候都不允许运行多个线程.

以下是您遇到链接问题的代码

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

    }

}
Run Code Online (Sandbox Code Playgroud)

在此先感谢Peter Bartolo

kar*_*rts 4

显然,SwingWorker在 JDK 1.6 中,s 默认情况下都在同一个后台线程上执行

添加这些

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
Run Code Online (Sandbox Code Playgroud)

在你的顶部Main()添加这个

final Executor executor = Executors.newCachedThreadPool();
Run Code Online (Sandbox Code Playgroud)

在你的s 中,像这样actionPerformed执行你的sSwingWorker

executor.execute(new Main.MyTask("First"));
Run Code Online (Sandbox Code Playgroud)

这将在线程池中的单独线程上执行每个 SwingWorker。