Java reuse artist

I am working on a simulation system where every time I have to model many models. I used FixedThreadPool to speed up the calculation:

ExecutorService executor = Executors.newFixedThreadPool(nThread); for (Model m : models) { executor.execute( m.simulationTask() ); } executor.shutdown(); while ( ! executor.awaitTermination(10, TimeUnit.MINUTES) ) { System.out.println("wait"); } 

Now, the executor cannot be used to execute() new tasks after calling shutdown() . Is there a way to reset an artist, so I can reuse an existing artist (and its threads) in the next modeling step?

+4
source share
4 answers

You can reuse the artist service if you change the structure of your code a little.

 Collection<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>(16); for (Model m : models) { tasks.add(m.simulationTask()); } ExecutorService executor = Executors.newFixedThreadPool(nThread); try { executor.invokeAll(tasks); } catch(InterruptedException ie) { // Handle this } 

Basically, you collect all your tasks, complete them, and wait for them to complete before continuing. Of course, you can also use the new Executor service for each of your time steps, but at least you have options.

Caveats : I did not compile the code so that there might be errors. I also suggested the Integer parameter type for convenience.

+7
source

You can write your own implementation of the Executor interface. In addition, most of the default implementation that I know uses reap threads and clears memory after shutdown() , so there is no (as far as I know) a pre-made solution.

Given that shutdown() is likely to make many cleanup and garbage collection failures, it’s not entirely clear why restarting is better than finding a new Executor , you might want to study the ThreadPoolExecutor extension tutorials using a set of pause / resume methods instead of adding disconnect options.

+1
source

Declare ExecutorService as a member of your class and reuse it as you want. Do not call shutdown () as it will not accept any additional tasks. Of course, your tasks should end beautifully, and they should also end at some point.

+1
source

Just get another ExecutorService . Overhead costs are minimal anyway.

If you insist on reusing the same artist, you can implement your own barrier mechanism. When sending a new task, atomically increase the counter. When the task ends, atomically decrease the counter. In the main thread, wait until the counter is zero. Sort of:

 // globally visible objects AtomicInteger counter = new AtomicInteger(0); Object signal = new Object(); ExecutorService executor = Executors.newFixedThreadPool(nThread); for (Model m : models) { counter.getAndIncrement(); executor.execute( m.simulationTask() ); } synchronized(signal) { while(count.get() > 0) { signal.wait(); } } 

Then inside the run your tasks:

 public void run() { // original code // at the end: synchronized(signal) { counter.getAndDecrement(); signal.notify(); } } 
0
source

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


All Articles