Understanding Java executorservice

I'm trying to learn how to use Java's executorservice,

I am reading the following discussion java thread simple queue

Here is an example

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

I tried to implement this solution, so I created a form and placed the start and stop buttons, but the problem I faced was that if I called this process on the start button, it would suspend the complete form, and we need to wait until all processes are completed

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

But so far, I can't understand how to make it work, because after clicking the start button, I should get access, assuming I want to stop the process

Someone can guide me in the right direction

thank you

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

problem

1) When the program is executed, the complete form remains frozen 2) The progress bar does not work. The status is displayed only after all processes are completed

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

}                                        

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://www.wikipedia.org/","http://en.wikipedia.org/wiki/Main_Page" };

    pbarStatus.setMaximum(hostList.length-1);
    pbarStatus.setValue(0);
    for (int i = 0; i < hostList.length; i++) {

        String url = hostList[i];
        Runnable worker = new MyRunnable(url);
        executor.execute(worker);
    }
    executor.shutdown();
    // 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;
    }

    @Override
    public void run() {

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

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

Solution

According to the executorservice API, this prevents:

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

API quotation:

If you don't want this to stop the current thread, you might call it in another thread. In addition, your application is swing, and then consider using swing worker. I think it uses "executorservices under the hood"

According to your latest code, I will use

>A swingworker to manage all background threads. > I give swingworker an executorservice > and an executorcompletionservice initialized with executorservice, so that I can get the task results when the task is completed > I fill it with callables instead of runnables, because this will allow the task to return something, perhaps a string to represent the progress. > I set the progress property of swingworker to (100 * taskcount) / totaltaskcount, and let my jpprogressbar from 0 to 100. > Then I use the publishing / processing method of swingworker to extract the callable returned string. > I'll use propertychangelister to monitor the progress of swingworker in the GUI > and then change the GUI from this listener. > I will change if (code = = 200) {to if (code = = httpurlconnection. Http_ok) {to avoid magic numbers. > JButton's action will disable itself, then create a new swingworker object, add the worker's properchangelistener to the worker, and 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;

@SuppressWarnings("serial")
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://crunchify.com","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.setVisibleRowCount(10);
      resultList.setPrototypeCellValue(String.format(LIST_PROTOTYPE_STRING,""));
      resultList.setFont(new Font(Font.MONOSPACED,Font.PLAIN,12));

      add(pbarStatus);
      add(doItButton);
      add(new JScrollPane(resultList,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
   }

   public void addToCompletionList(String element) {
      listModel.addElement(element);
   }

   public void setStatusValue(int progress) {
      pbarStatus.setValue(progress);
   }

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

      @Override
      public void actionPerformed(ActionEvent e) {
         setEnabled(false);
         DoItWorker worker = new DoItWorker(HOST_LIST,MYTHREADS);
         SwingExecutorCompletionService gui = SwingExecutorCompletionService.this;
         Propertychangelistener workerListener = new Workerchangelistener(gui,this);
         worker.addPropertychangelistener(workerListener);
         worker.execute();
      }
   }

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

      JFrame frame = new JFrame("Swing ExecutorCompletionService");
      frame.setDefaultCloSEOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokelater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

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;
   }

   @Override
   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
               .openConnection();
         connection.setRequestMethod("GET");
         connection.connect();

         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;
   }

   @Override
   public void propertyChange(PropertyChangeEvent evt) {
      DoItWorker worker = (DoItWorker)evt.getSource();
      if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
         action.setEnabled(true);
         try {
            worker.get();
         } catch (InterruptedException e) {
            e.printStackTrace();
         } catch (ExecutionException e) {
            e.printStackTrace();
         }
      } else if (DoItWorker.INTERMEDIATE_RESULT.equals(evt.getPropertyName())) {
         gui.addToCompletionList(evt.getNewValue().toString());
      } else if ("progress".equals(evt.getPropertyName())) {
         gui.setStatusValue(worker.getProgress());
      }
   }
}

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);
   }

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

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

   @Override
   protected void process(List<String> chunks) {
      for (String chunk : chunks) {
         setIntermediateResult(chunk);
      }
   }

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

}

Which looks and works as follows:

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>