Does ExecutorService inside SwingWorker use good practice?

Consider the following code:

SwingWorker<Void, Void> sworker = new SwingWorker<Void, Void>() { @Override protected Void doInBackground() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(5); try { for (int j = 0; j < 5; j++) { Callable<Object> worker = new MyCallableImpl(); Future<Object> future = executor.submit(worker); array[j] = future.get(); } } catch (InterruptedException e) { // some code here } catch (ExecutionException e) { // some code here } // some code here executor.shutdown(); return null; } }; sworker.execute(); 

As I said in the header: is it good practice to call ExecutorService inside the doInBackground () of the SwingWorker method? It works for me (JDK1.7), the GUI is not blocked, and several threads from the Executor pool are running in the background, but still I have some doubts ...

+6
source share
3 answers

The code above does not make much sense to me.

If the goal is to ensure that the GUI remains responsive during the execution of a long-running task, then there is no need to use ExecutorService , since SwingWorker already provides this mechanism.

+2
source

For further reply. This does not make sense because you are doing single-threaded. doInBackground will send to the performer and wait for the completion of this separate task, and then send another.

You should send the same path, but save the returned Future in a list of some kind, then go to each of them after sending all the tasks.

I do not really like doInBackground send these jobs asynchronously, as mre does. If you are trying to submit multiple assignments and submit only N at any given time, you should definitely not do this through SwingWorker.doInBackground . Using ExectorService + SwingUtilities.invokeLater , I think this is the best way.

And just to clear up any confusion, invokeLater should be used here only when the task in the ExecutorService is complete, and all she needs to do is update the user interface component.

Edit: example for your comment

 protected Void doInBackground() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(5); List<Future> futures = ...; try { for (int j = 0; j < 5; j++) { Callable<Object> worker = new MyCallableImpl(); futures.add(executor.submit(new Callable<Object>(){ public Object call(){ //expensive time consuming operation final String result = ...;//result from consuming operation SwingUtilities.invokeLater(new Runnable(){ public void run(){ jLabel.setText(result); } }); return new Object(); } )); } for(Future<Object> f :futures)f.get(); executor.shutdown(); return null; } 

Note how to make invokeLater for a simple upgrade? This should not cause your EDT to freeze.

+2
source
  • can execute SwingWorkers instance from Executor

  • must accept that the Contractor does not care about the life cycle of SwingWorkers and vice versa

  • need to implement PropertyChangeListener for SwingWorker

  • exmple here

+2
source

Source: https://habr.com/ru/post/911871/


All Articles