Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. When the application is run from the IDE (Netbeans), I can start multiple long running tasks simultaneously without any problem.

I created a runnable jar file for the application, in order to be able to run it from outside the 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. 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. 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.

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.

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

like image 905
PB_MLT Avatar asked May 24 '10 01:05

PB_MLT


People also ask

What will happen if multiple threads accessing the same resource in Java?

Multiple threads accessing shared data simultaneously may lead to a timing dependent error known as data race condition. Data races may be hidden in the code without interfering or harming the program execution until the moment when threads are scheduled in a scenario (the condition) that break the program execution.

Can multiple threads read the same file Java?

Multiple threads can also read data from the same FITS file simultaneously, as long as the file was opened independently by each thread. This relies on the operating system to correctly deal with reading the same file by multiple processes.

Where two or more threads wait for each other to execute?

The definition of a deadlock is when two or more threads cannot complete their execution because they are mutually blocked and waiting for something from the other thread(s).


1 Answers

Apparently, SwingWorkers by default all execute on the same background thread in JDK 1.6

Add these

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

At the top of your Main() add this

final Executor executor = Executors.newCachedThreadPool();

And in your actionPerformeds, execute your SwingWorkers like this

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

This will execute each SwingWorker on a separate thread in a Thread pool.

like image 100
karoberts Avatar answered Nov 10 '22 11:11

karoberts