Java 8 concurrency - Wait for tasks to shutdown executor - java

I am trying my first steps with Java 8 concurrency.
In the code example below, an exception is thrown because the my tasks sleep 2 seconds. The shutdown function waits 5 seconds for termination. Therefore, only two loops are executed. Is there a dynamic solution to this instead of counting the max time the execution could take and adjusting the value of the awaitTermination()-method?
public class Application {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
IntStream.range(0, 10).forEach(i ->
executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("Hello");
} catch (InterruptedException e) {
throw new IllegalStateException("Task interrupted", e);
}
})
);
shutdown(executor);
}
private static void shutdown(ExecutorService executor) {
try {
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.err.println("tasks interrupted");
} finally {
if (!executor.isTerminated()) {
System.err.println("cancel non-finished tasks");
}
executor.shutdownNow();
}
}

Adding to what #AdamSkyWalker mentioned you can use a CountDownLatch as you already know the no of Threads (10 in this case).
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(1);
final CountDownLatch latch = new CountDownLatch(10);
IntStream.range(0, 10).forEach(i ->
executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("Hello");
} catch (InterruptedException e) {
throw new IllegalStateException("Task interrupted", e);
} finally {
latch.countDown();
}
})
);
latch.await();
}
}
I wrote a post sometime back on comparing CountDownLatch, Semaphore and CyclicBarrier which will be helpful for you.

Related

How to throw Timeout exception for the task inside parallel stream

The code I want to achieve is as below:
StreamSupport.stream(jsonArray.spliterator(), true).forEach(s ->{
try {
//invoke other api and set timeout for its execution
}
catch(TimeoutException e) {
s.getAsJsonObject().addProperty("processStatus", "Failure");
}
});
Can anyone help me in achieving "invoke other api and set timeout for it's execution" case in the above snippet?
I don't think you can do that inside a stream, but you can wrap the execution in a Callable like so to achieve the same result:
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println(future.get(1, TimeUnit.SECONDS));
}catch (Exception e) {
future.cancel(true);
e.printStackTrace();
} finally {
executor.shutdownNow();
}
}
private static class Task implements Callable<String> {
#Override
public String call(){
IntStream.of(1,2,3,4,5,6,7,8,9).parallel().forEach(t -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
return "ok";
}
}

Java thread hangs after CompletionService.take()

I've got simple test code:
public static void main(String[] args) {
CompletionService<Integer> cs = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
cs.submit(new Callable<Integer>() {
public Integer call(){
try{
Thread.sleep(3000); // Just sleep and print
System.out.println("Sleeping thread: " + Thread.currentThread().getId());
}catch(InterruptedException e){
e.printStackTrace();
}
return 10;
}
});
try{
Future<Integer> fi = cs.take();
System.out.println(fi.get());
}catch(Exception e){
e.printStackTrace();
}
}
I run it, sleep 3 seconds, and prints
Sleeping thread: 14
10
But then it hangs there, the program doesn't end.
What's happening, how to make it finish?
As mentioned in the comments by tgdavies, your program will exit after +/- 60 seconds, because that is the default timeout for a thread without tasks in an ExecutorService created by Executors.newCachedThreadPool().
If you don't want to wait for 60 seconds, you should shutdown the executor service after you're done submitting tasks.
For example:
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
try {
CompletionService<Integer> cs = new ExecutorCompletionService<>(executorService);
cs.submit(new Callable<Integer>() {
public Integer call() {
try {
Thread.sleep(3000); // Just sleep and print
System.out.println("Sleeping thread: " + Thread.currentThread().getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
return 10;
}
});
try {
Future<Integer> fi = cs.take();
System.out.println(fi.get());
} catch (Exception e) {
e.printStackTrace();
}
} finally {
executorService.shutdown();
}
}
Alternatively, configure the executor service to create daemon threads using a custom ThreadFactory. Only do this if it is not a problem that an executor service that is doing actual work gets "killed" when there are no more normal (non-daemon) threads.

ScheduledExecutorService waits for task to complete, does pending tasks pile up to ultimately interrupting main thred?

I was curious for my new implementation using ScheduledExecutorService in which the task is expected to finish within 100ms period and 0ms delay. But in case if there is system load and its taking say 550 ms, would there be a queue maintained by ScheduledExecutorService for those pending 4 tasks? And then run as soon as (0ms delay) first one is finished. And what if second execution takes 560 ms , would that add another 4 threads to its queue?
There is not documentation around that, or I might be overlooking it. But I want to make sure that the pile up of such executions would trigger to leak or overflow.
For example: below code, could main thread ever fail?
private static ScheduledExecutorService consumerThreadPool = Executors.newSingleThreadScheduledExecutor();
public static void main(String[] args) throws Exception {
consumerThreadPool.scheduleAtFixedRate(() -> performTask(), 0, 1, TimeUnit.MILLISECONDS);
}
private static void performTask () {
try {
Thread.sleep(550);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Your tasks will be skipped if they overrun the next scheduled time, you can verify easily with System.out.println and alter the sleep under 500ms to 5000ms:
public static void main(final String[] args) throws InterruptedException, ExecutionException
{
var executor = Executors.newScheduledThreadPool(1);
var count = new AtomicInteger();
Runnable task = () -> {
String desc = "run("+((System.currentTimeMillis() / 1000) % 60)+") "+Thread.currentThread().getName()+" count "+count.incrementAndGet();
System.out.println(desc);
if(count.get() == 50)
throw new RuntimeException("I give up!");
try
{
Thread.sleep(2500);
}
catch (InterruptedException e)
{
System.out.println("Thread "+Thread.currentThread().getName()+" INTERRUPTED");
}
};
var future = executor.scheduleAtFixedRate(task, 5000, 1000, TimeUnit.MILLISECONDS);
System.out.println("Calling future.get() ...");
try {
var res = future.get();
System.out.println("future.get()="+res);
}
catch(Exception e)
{
System.err.println("There was an exception:" +e);
// Decide between "continue" or "throw e" here
// ...
}
executor.shutdownNow();
System.out.println("shutdown complete");
}

My program is not returning/ending with Executor

Given the following Java example, which uses multithreading:
import java.util.concurrent.*;
public class SquareCalculator {
private ExecutorService executor = Executors.newSingleThreadExecutor();
public Future<Integer> calculate(Integer input) {
return executor.submit( () -> {
Thread.sleep(1000);
return input * input;
});
}
public static void main(String[] args) {
try {
Future<Integer> future = new SquareCalculator().calculate(10);
while (!future.isDone()){
System.out.println("Calculating...");
Thread.sleep(300);
}
Integer result = future.get();
System.out.println("we got: " + result);
} catch(InterruptedException | ExecutionException e) {
System.out.println("had exception");
}
}
}
It produces:
java SquareCalculator
Calculating...
Calculating...
Calculating...
Calculating...
we got: 100
But the application is never terminating.
Am I suppose to join the thread or something?
Should be in comment but not enough reputation.
You should call shutdown on executor. You can get more details from below link:
Reason for calling shutdown() on ExecutorService
I bet you want to add something like this:
finally {
if (executor != null) {
executor.shutdown();
}
}
You need to shut down the executor framework towards the end of the program and wait until it gracefully terminates..
executor.shutdown();
try {
executor.awaitTermination(4 * 3600, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}

Force asynchronous operation to block current thread

I have an API that only supports asynchronously doing some operation, and I want to force it to block my thread.
static void doWorkSync(Worker worker) {
final Condition condition = new ReentrantLock().newCondition();
worker.doWorkAsync(() -> condition.signal());
try {
condition.await();
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}
Are Conditions, as used above, the sanest solution for this case?
CountDownLatch is what you're looking for!
static void doWorkSync(Worker worker) {
final CountDownLatch latch = new CountDownLatch(1);
worker.doWorkAsync(() -> latch.countDown());
try {
latch.await();
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}

Categories

Resources