Java executor service: Waiting for all tasks to finish - java

I am trying to introduce concurrency in my program. Structure of program is something like this:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
List<String> initialData = dao.fetchFromDB("input");
Queue queue = new MyQueue();
queue.add(initialData);
while(queue.length() > 0) {
int startingLength = queue.length();
for (int i = 0; i < startingLength; i++) {
String input = queue.remove();
if(input.equals("some value")) {
missionAccomplished = true;
break;
} else {
MyRunnable task = new MyRunnable(input, queue, dao);
executor.execute(task);
}
}
if(missionAccomplished) {
break;
}
executor.shutdown();
}
So queue contains the data needed to be processed one by one. Inside while loop I run a for loop which picks data from queue one by one sequentially and performs some check on it, and if check fails I create a runnable task with this data and hands it over to executor(as DB operation is time consuming, I want to use parallelism for it). for loop picks data only upto certain length in given iteration of while.
What I want to achieve is that 'while' loop goes to next iteration only when all tasks submitted to executor in current iteration are finished.
How can this be achieved?

try-with-resources in Project Loom
You asked:
What I want to achieve is that 'while' loop goes to next iteration only when all tasks submitted to executor in current iteration are finished.
Project Loom promises to make this simpler.
One of the changes brought by Project Loom is that the ExecutorService interface is a sub-interface of AutoCloseable. This means we can use try-with-resources syntax. The try-with-resources automatically blocks until all submitted tasks are done/failed/canceled — just what you asked for.
Also, the executor service is automatically shut down when exiting the try. These changes mean your code becomes simpler and clearer.
Also, for code that blocks often, such as database access, you will see dramatically faster performance using virtual threads (a.k.a. fibers). Virtual threads is another new feature of Project Loom. To get this feature, call Executors.newVirtualThreadExecutor.
Experimental builds of Project Loom are available now, based on early-access Java 17. The Loom team is asking for feedback. For more info, see recent presentations and interviews by Ron Pressler of Oracle.
System.out.println( "INFO - executor service about to start. " + Instant.now() );
try (
ExecutorService executorService = Executors.newVirtualThreadExecutor() ;
)
{
for ( int i = 0 ; i < 7 ; i++ )
{
executorService.submit( ( ) -> System.out.println( Instant.now() ) );
}
}
// Notice that when reaching this point we block until all submitted tasks still running are fin
// because that is the new behavior of `ExecutorService` being `AutoCloseable`.
System.out.println( "INFO - executor service shut down at this point. " + Instant.now() );
When run.
INFO - executor service about to start. 2021-02-08T06:27:03.500093Z
2021-02-08T06:27:03.554440Z
2021-02-08T06:27:03.554517Z
2021-02-08T06:27:03.554682Z
2021-02-08T06:27:03.554837Z
2021-02-08T06:27:03.555015Z
2021-02-08T06:27:03.555073Z
2021-02-08T06:27:03.556675Z
INFO - executor service shut down at this point. 2021-02-08T06:27:03.560723Z

Related

Looping Threads every 3 seconds in JavaFX

I'm currently working on a stock market application that changes the values of the prices of the stocks every so often (for this example, let's have the stocks change value every 3 seconds). I looked into doing tasks but I couldn't find a way to make the tasks run continuously. Is there a way to make a task loop every 3 seconds within the main class? (To clarify, I would like this looped task to be added into the body of my main method, without using external classes besides the main method)
Here's what I have so far:
Task<Void> change = new Task<Void>() {
#Override
protected Void call() throws Exception {
try {
Thread.sleep(3000);
}
catch (InterruptedException e) {}
return null;
}
};
change.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
}
});
new Thread(change).start();
NOTE: This code was referenced from here
Do not think in terms of “continuously” or “looping”. Instead think of the job to be done (look up fresh stock prices), and how often do you want that task to be performed.
For the first part, your task, define a Runnable (or Callable). That means simply having a run method to comply with the contract of the interface.
In lambda syntax:
Runnable runnable =
() -> {
System.out.println( "Looking up fresh stock prices at " + Instant.now().toString() ) ;
}
;
Next, study up on the Executors framework built into modern Java. See Oracle Tutorial. This framework greatly simplifies the tricky work of scheduling work on threads.
Specifically, you want to use ScheduledExecutorService. This interface is for scheduling a task to run once at a specific time (actually, run once after a specific delay expires), or run a task repeatedly. You, of course, want the latter.
Get an implementation from the Executors class. For your needs, we need only a single-thread. In other cases, you may want to use a thread pool.
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor() ;
You have a choice two variations for scheduling: scheduleAtFixedRate​ and scheduleWithFixedDelay​. Study them both to decide which is best for your case. In either case, know that you cannot rely on the scheduling perfectly. Your host OS controls granting access to the CPU cores to the JVM, and the JVM may be juggling a multitude of threads. So the timing may be delayed sporadically, though for most business apps the delays should be insignificant.
ses.scheduleWithFixedDelay( runnable , 0L , 3L , TimeUnit.SECONDS ) ;
You may want to capture the returned ScheduledFuture object to monitor progress or completion. Our line of code above ignores it.
IMPORTANT Be sure to gracefully shutdown your executor service when no longer needed, or when your app is being shut down. Otherwise your threads may continue running in the background, surviving your app's exit.
IMPORTANT Wrap the task inside your Runnable task with a try-catch. Any exception or error thrown that bubbles up to the level of the Runnable object will result in your executor service silently terminating. No further calls will be scheduled. Search Stack Overflow to learn more.
Runnable runnable =
( ) -> {
try
{
System.out.println( "Looking up fresh stock prices at " + Instant.now().toString() );
}
catch ( Exception e )
{
// … try to recover, if you want the scheduled executor service to continue scheduling this task.
// Or, at least, do logging/notifications to know when and why the scheduling of this task halted.
e.printStackTrace();
}
};
IMPORTANT Never access/modify any user-interface widget from a background thread when using UI frameworks like JavaFX, Swing, or Vaadin. Each UI framework will provide its own mechanism by which you can schedule widget-updating work to be performed on the UI’s thread. I am not familiar with JavaFX, so I cannot be more specific.
Put all that together in this example code. And, for those not comfortable with lambda syntax, use an anonymous class for our Runnable.
package work.basil.example;
import java.time.Instant;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Bogus
{
public static void main ( String[] args )
{
Runnable runnable =
new Runnable()
{
#Override
public void run ( )
{
try
{
System.out.println( "Looking up fresh stock prices at " + Instant.now().toString() );
}
catch ( Exception e )
{
// … try to recover, if you want the scheduled executor service to continue scheduling this task.
// Or, at least, do logging/notifications to know when and why the scheduling of this task halted.
e.printStackTrace();
}
}
};
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleWithFixedDelay( runnable , 0L , 3L , TimeUnit.SECONDS );
try
{
Thread.sleep( TimeUnit.MINUTES.toMillis( 1 ) );
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
finally
{
ses.shutdown(); // IMPORTANT Always shutdown gracefully your executor service so the thread pool does not outlive your app.
}
System.out.println( "INFO - Completed run at: " + Instant.now() );
}
}
When run.
Looking up fresh stock prices at 2020-02-15T06:35:35.987199Z
Looking up fresh stock prices at 2020-02-15T06:35:39.026132Z
Looking up fresh stock prices at 2020-02-15T06:35:42.030302Z
Looking up fresh stock prices at 2020-02-15T06:35:45.035176Z
…
Looking up fresh stock prices at 2020-02-15T06:36:30.097743Z
Looking up fresh stock prices at 2020-02-15T06:36:33.100713Z
INFO - Completed run at: 2020-02-15T06:36:35.988752Z
As mentioned above, notice how the tasks are not exactly three seconds apart, but are pretty close. This example was run on a Mac mini with 6 real cores and no hyper-threading, 32 gigs of memory, on macOS Mojave, with Java 13.

Using Executors in very high-load environment

I manage to write a REST API using Stripe Framework. Inside my API, I have several tasks which need to execute and combine their results. I come up with an approach, borrowed from JavaScript, which will spawn tasks into several threads and join rather than chronological implementation. Thus, I used ExecutorService but I found a bottleneck on the implementation when the number of requests is quite big, tasks are finished on a longer time than I expect.
My question is related to an alternate way to achieve the same purpose.
How can I create an Executors per request
How can I expand Executors' size
To demonstrate, let consider this way on Javascript
import Promise from 'bluebird';
let tasks = [];
tasks.push(task01);
tasks.push(task02);
Promise.all(tasks).then(results => { do_sth_here!} )
Bring this idea to Java, I have implemented like below
ExecutorService exec = Executors.newCachedThreadPool();
List<Callable<Promise>> tasks = new ArrayList<>();
List<Future<Promise>> PromiseAll;
try {
tasks.add(() -> TaskPromises(Input));
tasks.add(() -> TaskPromise(Input));
PromiseAll = exec.invokeAll(tasks);
for (Future<Promise> fr : PromiseAll) {
// do_some_thing_next
}
}

Android Java Running List of Action In separate Thread similar to C# style

I'm .NET Developer but i have to make some code for Android in Java. I need to run 4 calculation operation and i want to make it in separate threads. I can simply create 4 thread and just run it but when device will have less than 4 cores ( e.g 1) it will be same or even less effective like just run in one thread. In C# i can create list of Action and then just run it in Parrarel like this :
C# CODE :
var actions = new List<Action>
{
() => { // some action1},
() => { // some action2},
() => { // some action3},
() => { // some action4},
}
Parallel.ForEach(actions, new ParallelOptions { MaxDegreeOfParallelism = GetCoreCount() }, x => x());
And this will run and this will guarantee that each Action will be process on separate core ( More-Less)
Can I do some thing like this in Java on Android ?
I have no idea how to start this.
Only one thing that come to my head is some like this but this is ugly and ineffective.
int cores = Runtime.getRuntime().availableProcessors();
if(cores = 1)
{
// Create 1 Thread with action1,action2,action3,action4
}
if(cores = 2)
{
// Create 1 Thread with action1,action2
// And Create 2nd Thread with action3,action4
}
if(cores = 3)
{
// Create 1 Thread with action1,
// And Create 2nd Thread with action2
// And Create 3rd Thread with action3
// Thread that first end his action will pick up Action4
}
if(cores >= 4)
{
// Create 1 Thread with action1,
// And Create 2nd Thread with action2
// And Create 3nd Thread with action3
// And Create 4th Thread with action4
}
See even not codded this look very unclear and dirty ( and what when i add 5th action ? or will have 8 action and 8 cores ? )
Can i do something similar to C# ? With List of Action and Parallel execution limited by numbers of core ?
Thanks for advises :)
Try using a threadPoolExecutor https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
Java handles the efficiency issues your worried about, and fyi a computer with one core/cpu will have multiple threads running, there will only be one running at any given time. But any modern computer has a lot of threads running simultaneously, it doesn't depend on how many cores/cpus are present/available.

Interrupt java thread running nashorn script

In the code below i have javascript running in a separate thread from the main one. That script is an infinite loop, so it needs to be terminated somehow. How?
Calling .cancel() is not working AFTER the script begins running. But if i call .cancel() just after the thread initialization, it will terminate it (the commented out line).
package testscriptterminate;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.Timer;
import java.util.TimerTask;
public class TestScriptTerminate extends TimerTask{
private ExecutorService threads;
private Future runScript;
private Timer t;
public TestScriptTerminate(){
t = new Timer();
t.schedule(this, 6000); //let the script run for a while before attempt to cancel
threads = Executors.newFixedThreadPool(1);
runScript = threads.submit(new ScriptExec());
//runScript.cancel(true); //will cancel here, before the script had a change to run, but useless, i want to cancel at any time on demand
}
#Override
public void run(){
//after script has fully initialized and ran for a while - attempt to cancel.
//DOESN'T WORK, thread still active
System.out.println("Canceling now...");
runScript.cancel(true);
}
public static void main(String[] args) {
new TestScriptTerminate();
}
}
class ScriptExec implements Runnable{
private ScriptEngine js;
private ScriptEngineManager scriptManager;
public ScriptExec(){
init();
}
#Override
public void run() {
try {
js.eval("while(true){}");
} catch (ScriptException ex) {
System.out.println(ex.toString());
}
}
private void init(){
scriptManager = new ScriptEngineManager();
js = scriptManager.getEngineByName("nashorn");
}
}
So this is old, but i just wrote this up and thought it would probably be valuable to share. By default there is ~nothing you can do to stop a Nashorn script executing, .cancel() Thread.stop() Thread.interrupt() do nothing, but if you are willing to put in a bit of effort and are ok with rewriting some bytecode, it is achieveable. Details:
http://blog.getsandbox.com/2018/01/15/nashorn-interupt/
JavaScript (under Nashorn), like Java, will not respond to an interrupt in the middle of a tight loop. The script needs to poll for interruption and terminate the loop voluntarily, or it can call something that checks for interruption and let InterruptedException propagate.
You might think that Nashorn is "just running a script" and that it should be interrupted immediately. This doesn't apply, for the same reason that it doesn't apply in Java: asynchronous interruption risks corruption of the application's data structures, and there is essentially no way to avoid it or recover from it.
Asynchronous interruption brings in the same problems as the long-deprecated Thread.stop method. This is explained in this document, which is an updated version of the document linked in the comments.
Java Thread Primitive Deprecation
See also Goetz, Java Concurrency In Practice, Chapter 7, Cancellation and Shutdown.
The easiest way to check for interruption is to call Thread.interrupted(). You can call this quite easily from JavaScript. Here's a rewrite of the example program that cancels the running script after five seconds:
public class TestScriptTerminate {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
void script() {
ScriptEngineManager scriptManager = new ScriptEngineManager();
ScriptEngine js = scriptManager.getEngineByName("nashorn");
try {
System.out.println("Script starting.");
js.eval("while (true) { if (java.lang.Thread.interrupted()) break; }");
System.out.println("Script finished.");
} catch (ScriptException ex) {
ex.printStackTrace();
}
}
void init() throws Exception {
Future<?> scriptTask = pool.submit(this::script);
pool.schedule(() -> {
System.out.println("Canceling now...");
scriptTask.cancel(true);
}, 5, TimeUnit.SECONDS);
pool.shutdown();
}
public static void main(String[] args) throws Exception {
new TestScriptTerminate().init();
}
}
Since we're starting up a thread pool, might as well make it a scheduled thread pool so that we can use it for both the script task and the timeout. That way we can avoid Timer and TimerTask, which are mostly replaced by ScheduledExecutorService anyway.
The usual convention when handling and interrupt is either to restore the interrupt bit or to let an InterruptedException propagate. (One should never ignore an interrupt.) Since breaking out of the loop can be considered to have completed the handling of the interrupt, neither is necessary, and it seems sufficient simply to let the script exit normally.
This rewrite also moves a lot of work out of the constructor into an init() method. This prevents the instance from being leaked to other threads from within the constructor. There is no obvious danger from this in the original example code -- in fact, there almost never is -- but it's always good practice to avoid leaking the instance from the constructor.
Unfortunately it does not work for simple infinite loops: while (true) { }. I tried Thread.cancel(); does not cause the thread to exit. I wanted something foolproof for running scripts in an IntelliJ plugin where a user can make a mistake an cause an infinite loop, hanging the plugin.
The only thing I found to work in most cases is Thread.stop(). Even that does not work for a script like this:
while(true) {
try {
java.lang.Thread.sleep(100);
} catch (e) {
}
}
javascript catches the java.lang.ThreadDeath exception and keeps going. I found that the above sample is impossible to interrupt even with several Thread.stop() issued one after the other. Why would I use several? Hoping that one of them will catch the thread in its exception processing code and abort it. Which does work if there is something in the catch block to process as simple as var i = "" + e; that is enough to cause the second Thread.stop() to end it.
So the moral of the story is there is no fail safe way of ending a runaway script in Nashorn, but there is something that will work on most cases.
My implementation issues a Thread.interrupt(), then politely waits 2 seconds for the thread to terminate and if that fails then it issues Thread.stop() twice. If that does not work, then nothing else will either.
Hope it helps someone eliminate hours of experimentation to find a more reliable method to stop nashorn runaway scripts than hoping on the cooperation of the running script to respect Thread.cancel().
I have a similar problem where I let users write their own scripts.
But before I allow the script to be executed, I parse the script.
and if I find any of the following
(System.sleep. Exit, Thread.sleep, goto) etc
I don't even start the script, and I give user an error.
and then I do a search for all
(for,loops, while, doWhile), and I inject a method.
checkForLoop() just after the loop identifier.
I inject checkForLoop(); into allow user submitted script.
while(users code)
{
}
becomes
while ( checkForLoop() && users code )
{
}
This way before every iteration of their loop, my method is called.
and I can count how many times I was called or check internal timers.
Than I can stop the loops or timers from inside checkForLoop();
Honestly I think its a big security issue anyway, just to blindly let users write script and just execute it.
You need to build in a system that injects your code into their code loops.
Which is not that hard.
There are 100s of safety mechanisms you can apply to users submitted code, there is no RULE that says you need to run their code as is.
I have edited this answer to include a very simple example.
//Step 1
put the users submitted JS code into a Java String called userJSCode;
Step 2
//inject code at the start of their code.
String safeWhile ="var sCount=0; var sMax=10;
function safeWhileCheck(){ sCount++;
if ( return ( sCount > sMax )}";
userJSCode = safeWhile + userJSCode;
//Step 3: inject the custom while code
String injectSsafeWHile = "while( safeWhileCheck() && ";
userJSCode = userJSCode.replace("while(", injectSsafeWHile);
//Step 4: execute custom JS code
nashhorn.execute(injectSsafeWHile);
//Here is users bad submitted code, note no i increment in the loop, it would go on for ever.
var i=0;
while ( i <1000 )
console.log("I am number " + i);
using the steps above we end up with
var sCount=0;var sMax=10;
function safeWhileCheck(){
sCount++;
return ( sCount > sMax )};
var i=0;
while ( safeWhileCheck() && i <1000 )
console.log("I am number " + i)"
Here the while loop only executes a max of 10 times, so whatever you set the limit to.

java multi-threading

I'm executing a batch file using java command and reading batch data in text file putting in database. For example I have to run for 430 nodes within 15 min interval using same batch file. So I divided 430 node in 12 threads, so each thread contains 40 nodes pointing same batch file . But threads running parallel are not able wait for the batch file command to complete. I can't make wait for each thread, because all task should complete within 15 min. Any suggestions?
Below is piece of code running multi-threading.
for (int i = 0; i < noOfMainThreads; i++) {
// running 12 thread for 40 node
threadArr[i] = new Thread(runnableArr[i]);
runnableArr[i] = new CodeBatchfile(nodeArr,nodeidArr);
}
for (int i = 0; i < noOfMainThreads; i++) {
threadArr[i].start;
}
class CodeBatchfile{
void run(){
for (int i=1;i<nodename.length;i++) {
// exciting batch file using 12 threads.
cmd = filepath + " " + nodenamelocal;
try {
process = Runtime.getRuntime().exec(cmd, null, bdir);
process.waitFor();
}
catch(Exception ex) {
System.out.println("Exception Running batch file" + ex.getLocalizedMessage());
}
}
}
Use ExecutorService instead. Build a pipeline where each step works like this:
Create a job object which has all the information to do the task and which contains fields for the results. Create all job objects and put them into the queue for the service to run them.
So the first step would be to create 430 jobs to run the batch program. Each job would start the batch program and wait for it to terminate. After the batch terminates, you read the output and put that into the job instance.
Create an executor which runs N jobs in parallel. You will need to tune N; if it's a CPU intensive task, N == number of cores. if it's an IO intensive job, try higher values (2-4 times the CPU cores usually work well).
Put all the jobs into the executor's queue. Wait for jobs that finish, create new jobs from them and put them into the input queue of the executor.
Keep a job counter (started, finished) so you know when to stop.
Tutorial.
I think you should use CyclicBarrier, barrier allow you to wait in specific point until all the threads reach to the barrier, so after executing the batch you should call the wait of the cyclicBarrier. a good code example can be found here:
enter link description here

Categories