簡體   English   中英

如何使用可運行的jar文件執行多線程解決Java問題?

[英]How to resolve Java issue with multiple threads when executing with a runnable jar file?

我開發了一個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");
        }

    }

}

在此先感謝Peter Bartolo

顯然, SwingWorker默認情況下都在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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM