Search code examples
javaswingthreadpoolexecutorserviceswingworker

How to correctly use ExecutorService to manage the number of concurrently running SwingWorkers?


I am generating SwingWorkers based on a number of connections I need to make. I am trying to make it so that I set a fixed number of maximum concurrant SwingWorkers and when one of those finishes another one is started (or many others are started if many have finished). Based on http://java.dzone.com/articles/multi-threading-java-swing I am setting up the basic SwingWorker like this:

SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
        @Override
        protected Boolean doInBackground() throws Exception {

                        System.out.println("One SwingWorker just ran! ");
                }

                return true;
        }

        // Can safely update the GUI from this method.
        protected void done() {

                boolean status;
                try {
                        // Retrieve the return value of doInBackground.
                        status = get();
                        statusLabel.setText("Completed with status: " + status);
                } catch (InterruptedException e) {
                // This is thrown if the thread's interrupted.
                } catch (ExecutionException e) {
                // This is thrown if we throw an exception
                // from doInBackground.
                }
        }


};

worker.execute();


Now I'm uncertain in how to implement the mechanism I described above.

From https://stackoverflow.com/a/8356896/988591 I saw that I can use an ExecutorService to execute instances of SwingWorker and that this interface also allows to set the number of threads:

int n = 20; // Maximum number of threads
ExecutorService threadPool = Executors.newFixedThreadPool(n);
SwingWorker w; //don*t forget to initialize
threadPool.submit(w);

I think this is what I need but I don't know how to put the whole thing together (..I am also quite new to Java..). Could someone guide me a bit in the process of implementing this? Say at the top I have int totalTask = 100; Maybe it's just a matter of some loops but I can't seem to find any really easy-to-follow examples around and I just can't totally wrap my mind around it yet so.. I would appreciate some help! Thanks.


UPDATE: I have set up the ExecutorService this way:

ExecutorService executorService = Executors.newFixedThreadPool(500);

for (int i = 0; i < 20 ; i++) {

    executorService.submit(worker); 
    //I tried both...
    //executorService.execute(worker);
}


and I have removed worker.execute() called after the SwingWorker above but the output from console is just a single "One SwingWorker just ran!" line, how is that ? What did I do wrong?


Solution

  • That moment when you think: It was so obvious!

    ExecutorService executorService = Executors.newFixedThreadPool(20);
    
    for (int i = 0; i < 500; i++) {
    
            SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
                    @Override
                    protected Boolean doInBackground() throws Exception {
    
                            System.out.println("One SwingWorker just ran!");
                            return true;
                    }
    
    
                    protected void done() {
    
                            boolean status;
                            try {
    
                                    status = get();
    
                            } catch (InterruptedException e) {
                            // This is thrown if the thread's interrupted.
                            } catch (ExecutionException e) {
                            // This is thrown if we throw an exception
                            // from doInBackground.
                            }
                    }
    
            };
    
    
            executorService.submit(worker);
    }
    


    It works great!