10

I want to be able to use SwingWorker subclass multiple times. Is this possible?

I have read in the java doc:

SwingWorker is only designed to be executed once. Executing a SwingWorker more than once will not result in invoking the doInBackground method twice.

Line
  • 1,529
  • 3
  • 18
  • 42
Feras Odeh
  • 9,136
  • 20
  • 77
  • 121
  • 1
    Do you mean you want to reuse your SwingWorker implementation class, or and instance of the class? – Qwerky Oct 04 '10 at 11:18
  • I don't know maybe I got something wrong but when I create worker instances and call execute() method nothing get executed. However when I tried to call the doInBackground() method the workers executed – Feras Odeh Oct 04 '10 at 14:57

4 Answers4

10

One instance of a class implementing SwingWorker can be indeed ran only once. There are no limitations on instantiating as many instances as you need and running them.

Boris Pavlović
  • 63,078
  • 28
  • 122
  • 148
  • 1
    There is a limitation, the fact that multiple Objects must be garbage collected doing this makes it a limitation. For the small apps this may not matter, but for extremely large applications that are forced to minimize the number of things that get garbage collected for performance reasons, this is a limitation. Saying, straight out, that there are no limitations is not correct...just because it doesn't apply to everyone doesn't make it not a thing. – searchengine27 Dec 14 '15 at 22:31
  • Have you read the limita tihon of the class? It's not going to work if an instance is executed more than once. There's no alternative. And if the memory is a limitation most probably Java is not the right solution. So, if Java is used and there's enough memory there are no limitations. For bigger applications that's also a no problem. They have to be designed for partial garbage collection. Extreme cases may need something like a Disruptor, but then there's no sense having UI built in Swing – Boris Pavlović Dec 15 '15 at 06:20
  • 1
    Umm...there is an alternative. Have a single instance of a runnable, and a `ExecutorService`. Even in the `SwingWorker` documentation, it says that is a convenience class. There are easily other alternatives. `SwingWorker` is only appropriate when you can forgo certain things for others. – searchengine27 Dec 15 '15 at 16:12
  • If after having the performance measured multiple instances of `SwingWorker` are found to be a bottleneck, then, yeah, optimize it. For a regular code it should be used as a standard way of deferring UI tasks so other programmers or even the author herself could understand it later. In my opinion most probably some other things are going to cause problems before `SwingWorker`. – Boris Pavlović Dec 15 '15 at 16:16
1

You cannot instantiate as many instances you need and execute them. In SwingWorker class exists javax.swing.SwingWorker.MAX_WORKER_THREADS = 10. So you can execute a maximum 10 instances. An instance is freed only it spend 10 minutes in idle time. Do not use SwingWorker instance as a Thread instance;it is not a thread.

0

Try doing this:

  private void startTask() {// main method that creates the background task or class that implements the SwingWorker

    AppContext  appContext = AppContext.getAppContext();
    if(appContext!=null){
        appContext.remove(SwingWorker.class); 
    } 
    MassiveMigrationTask task = new MassiveMigrationTask();// class that implements the SwingWorker
    task.execute();// this process implicitly adds the SwingWorker.class to the appContext
    }

As the description: "The AppContext is a table referenced by ThreadGroup which stores application service instances."

So this issue is happening basically because the AppContext is saving the name of the thread called SwingWorker..., so if you try creating another instance of the thread you'll probably have no success, because it evaluates that thread name before executing a new one or at least put the new in the heap of threads to be executed, feel free consulting the code here:

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/awt/AppContext.java

PS: Important :"If you are not writing an application service, or don't know what one is, please do not use this class"

kar
  • 11
  • 1
0

You can just call again your swing worker from done() method (depend how your code desinged)

MySwingWorker worker = new MySwingWorker();
worker.setData(this.getData());
worker.execute();

Regard setData() and getData()

It's just simple hashmap i'm using to pass the inputs data to my swing worker, so for rerun it, i just passed the same inputs to the new instance of swing worker

Adir Dayan
  • 1,308
  • 13
  • 21