Understanding Java ExecutorService

I am trying to find out how to use Java executorservice,

I read the following discussion Simple Java Thread Queue

This example has an example

ExecutorService service = Executors.newFixedThreadPool(10);
// now submit our jobs
service.submit(new Runnable() {
    public void run() {
// you can submit any number of jobs and the 10 threads will work on them
// in order
// when no more to submit, call shutdown
// now wait for the jobs to finish
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);


I tried to implement this solution, for this I created one form and put a start and stop button, but the problem I ran into is if I call this process on the start button, it will hang in full form and we need to wait until the whole process ends.

I also tried to read the following https://www3.ntu.edu.sg/home/ehchua/programming/java/J5e_multithreading.html

but so far I can’t figure out how to get it to work since after clicking the start button I have to access back, suppose I want to stop the process.

Can someone please point me in the right direction.


To make my situation clearer, I add the code I'm testing.


1) the full form remains frozen while the program is running. 2) Progressbar does not work, displays status only after completion of the process.

private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {                                         


private void btnStopActionPerformed(java.awt.event.ActionEvent evt) {                                        
    flgStop = true;

   private static final int MYTHREADS = 30;
private boolean flgStop = false;
public  void TestConneciton() {
    ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
    String[] hostList = { "http://crunchify.com", "http://yahoo.com",
            "http://www.ebay.com", "http://google.com",
            "http://www.example.co", "https://paypal.com",
            "http://bing.com/", "http://techcrunch.com/",
            "http://mashable.com/", "http://thenextweb.com/",
            "http://wordpress.com/", "http://wordpress.org/",
            "http://example.com/", "http://sjsu.edu/",
            "http://ebay.co.uk/", "http://google.co.uk/",
            "http://en.wikipedia.org/wiki/Main_Page" };

    for (int i = 0; i < hostList.length; i++) {

        String url = hostList[i];
        Runnable worker = new MyRunnable(url);
    // Wait until all threads are finish
//        while (!executor.isTerminated()) {
//        }
    System.out.println("\nFinished all threads");

public  class MyRunnable implements Runnable {
    private final String url;

    MyRunnable(String url) {
        this.url = url;

    public void run() {

        String result = "";
        int code = 200;
        try {
            if(flgStop == true)
                //Stop thread execution
            URL siteURL = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) siteURL

            code = connection.getResponseCode();
            if (code == 200) {
                result = "Green\t";
        } catch (Exception e) {
            result = "->Red<-\t";
        System.out.println(url + "\t\tStatus:" + result);



source to share

3 answers

In the ExecutorService API, this block:

service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);


API quote:

Blocks until all tasks have finished executing after a shutdown request, or timed out, or the current thread is interrupted, whichever comes first.

If you don't want this to block the current thread, then perhaps you should call it on a different thread. Also, this is your Swing application, then consider using SwingWorker, which I believe uses ExecutorServices "under the hood".

Based on your last piece of code, I would use

  • SwingWorker for managing all background threads.
  • I would provide SwingWorker ExecutorService
  • and also an ExecutorCompletionService that was initialized with an ExecutorService, as this would allow me to capture the results of the task as they complete.
  • I would fill it with Callables, not Runnables, as that would allow the task to return something, perhaps a String to indicate progress.
  • I would set the SwingWorker progress property to (100 * taskCount) / totalTaskCount and have my JProgressBar between 0 and 100.
  • I then used the SwingWorker publish / process method pairs to retrieve the strings returned by the callee.
  • I would listen to the SwingWorker move in my GUI with PropertyChangeListener
  • And then make changes to the GUI from this listener.
  • I would change if (code == 200) {

    to if (code == HttpURLConnection.HTTP_OK) {

    to avoid magic numbers.
  • The JButton Action will detach itself, then create a new SwingWorker object, add the worker's ProperChangeListener to the worker, then execute the worker.

for example

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class SwingExecutorCompletionService extends JPanel {
   public static final int MYTHREADS = 10;
   private static final int LIST_PROTOTYPE_SIZE = 120;
   private static final String LIST_PROTOTYPE_STRING = "%" + LIST_PROTOTYPE_SIZE + "s";
   public static final String[] HOST_LIST = { 
      "http://en.wikipedia.org/wiki/Main_Page" };

   private JProgressBar pbarStatus = new JProgressBar(0, 100);
   private JButton doItButton = new JButton(new DoItAction("Do It", KeyEvent.VK_D));
   private DefaultListModel<String> listModel = new DefaultListModel<>();
   private JList<String> resultList = new JList<>(listModel);

   public SwingExecutorCompletionService() {
      resultList.setPrototypeCellValue(String.format(LIST_PROTOTYPE_STRING, ""));
      resultList.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));

      add(new JScrollPane(resultList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 

   public void addToCompletionList(String element) {

   public void setStatusValue(int progress) {

   class DoItAction extends AbstractAction {
      public DoItAction(String name, int mnemonic) {
         putValue(MNEMONIC_KEY, mnemonic);

      public void actionPerformed(ActionEvent e) {
         DoItWorker worker = new DoItWorker(HOST_LIST, MYTHREADS);
         SwingExecutorCompletionService gui = SwingExecutorCompletionService.this;
         PropertyChangeListener workerListener = new WorkerChangeListener(gui, this);

   private static void createAndShowGui() {
      SwingExecutorCompletionService mainPanel = new SwingExecutorCompletionService();

      JFrame frame = new JFrame("Swing ExecutorCompletionService");

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {

class MyCallable implements Callable<String> {
   private static final String RED = "->Red<-";
   private static final String GREEN = "Green";
   private final String url;
   private volatile boolean flgStop;

   MyCallable(String url) {
      this.url = url;

   public String call() throws Exception {
      String result = "";
      int code = HttpURLConnection.HTTP_OK;
      try {
         // if(flgStop == true)
         if (flgStop) {
            // Stop thread execution
         URL siteURL = new URL(url);
         HttpURLConnection connection = (HttpURLConnection) siteURL

         code = connection.getResponseCode();

         // No don't set the prog bar in a background thread!
         // !! pbarStatus.setValue(pbarStatus.getValue()+1); 
         // avoid magic numbers
         if (code == HttpURLConnection.HTTP_OK) {
            result = GREEN;
      } catch (Exception e) {
         result = RED;
      return String.format("%-40s %s", url + ":", result);


class WorkerChangeListener implements PropertyChangeListener {
   private Action action;
   private SwingExecutorCompletionService gui;

   public WorkerChangeListener(SwingExecutorCompletionService gui, Action button) {
      this.gui = gui;
      this.action = button;

   public void propertyChange(PropertyChangeEvent evt) {
      DoItWorker worker = (DoItWorker)evt.getSource();
      if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
         try {
         } catch (InterruptedException e) {
         } catch (ExecutionException e) {
      } else if (DoItWorker.INTERMEDIATE_RESULT.equals(evt.getPropertyName())) {
      } else if ("progress".equals(evt.getPropertyName())) {

class DoItWorker extends SwingWorker<Void, String> {
   public static final String INTERMEDIATE_RESULT = "intermediate result";
   private static final long TIME_OUT = 5;
   private static final TimeUnit UNIT = TimeUnit.MINUTES;

   private String intermediateResult;
   private ExecutorService executor;
   private CompletionService<String> completionService;
   private String[] hostList;

   public DoItWorker(String[] hostList, int myThreads) {
      this.hostList = hostList;
      executor = Executors.newFixedThreadPool(myThreads);
      completionService = new ExecutorCompletionService<>(executor);

   protected Void doInBackground() throws Exception {
      for (int i = 0; i < hostList.length; i++) {

         String url = hostList[i];
         Callable<String> callable = new MyCallable(url);
      for (int i = 0; i < hostList.length; i++) {
         String result = completionService.take().get();
         int progress = (100 * i) / hostList.length;
      executor.awaitTermination(TIME_OUT, UNIT);
      return null;

   protected void process(List<String> chunks) {
      for (String chunk : chunks) {

   private void setIntermediateResult(String intermediateResult) {
      String oldValue = this.intermediateResult;
      String newValue = intermediateResult;
      this.intermediateResult = intermediateResult;
      firePropertyChange(INTERMEDIATE_RESULT, oldValue, newValue);



What will look and run like:

enter image description here



If you are using a JButton

, with yours ExecutorService

, then you should probably create a new thread and issue a Thread Dispatch Thread (EDT):

button.setActionListener(new Action() {
  public void actionPerformed(ActionEvent e) {
    button.setEnabled(false); // disable the button 
    new Thread(new Runnable() {
      public void run() {
        ... your code ...


Like Hovercraft Full of Eels, it awaitTermination

is a blocking operation.

And in the case of Swing, you are probably doing it in Action (like in my example) and you are blocking the EDT from performing various operations such as responding to user input :)

Note. ExecutorService

has a nice invokeAll that might be a little more useful than using awaitTermination

. This also blocks, and you still have to do your things on a different thread if needed.



If you want to cancel already started tasks, you will need to use Callable

instead Runnable

. When you submit the job, you return Future

, which you can call cancel ().

public static void main(String[] args) {
  ExecutorService es = Executors.newFixedThreadPool(10);
  Callable<Integer> callable1 = new CallableImpl();
  Future<Integer> future1 = es.submit(callable1);

  // if you decide to cancel your task gracefully


Then you need to handle ThreadInterrupt

in your Callable implementation.

public class CallableImpl implements Callable<Integer> {
public Integer call() throws Exception {
     try {
        while(true) {               
            // do something

            if(Thread.currentThread().isInterrupted()) {
                System.out.println("detected interrupt flag");
    catch(InterruptedException ie) {


@Hovercraft is probably right, if you are coding a Swing application then SwingWorker is what you want to use.



All Articles