I have a async function that calls other async function. In Java, how to wait on untill the async call completes(including any nested async calls in it).
I already Future callable But no luck.
Sample code:
void asyncMehodA(){ }
void asyncMethodB() {
asyncMehodA();
}
I tried the Future callable in the following way:
final Callable<Void> callable1 = new Callable<Void>() {
#Override
public Void call() {
asyncMethodB();
return null;
}
};
final Future<Void> callableFuture = mExecutor.submit(callable1);
try {
callableFuture.get();
} catch (final InterruptedException | ExecutionException e) {}
hoping that the get function will block the execusion untill the async return. But seems the get function will fire the async call and reurn null. not waiting for the asycn to complete its execusion. I added log statements in the verified the same. Please correct me if my understanding is wrong. suggest any other concepts that can aid me.
Here is an example using CountDownLatch.
package chapter13;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class BST {
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final ExecutorService executorService = Executors.newCachedThreadPool();
Runnable runnableA = () -> {
System.out.println("Runnable A");
latch.countDown();
System.out.println("Runnable A finished");
};
Runnable runnableB = () -> {
System.out.println("Runnable B");
executorService.submit(runnableA);
try {
System.out.println("Runnable B waiting for A to complete");
latch.await();
System.out.println("Runnable B finished");
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
Thread.currentThread().interrupt();
}
};
executorService.submit(runnableB);
Thread.sleep(10);
shutDown(executorService);
}
private static void shutDown(ExecutorService executorService) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(1, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}
}
}
I use Thread.sleep() method to sleep the main thread, because shuting down the pool immediately after task B was submitted, might cause the pool to stop accepting new tasks before task A is submitted by task B.
One way would be to use a java locking method.
An example:
private AtomicBoolean processed = new AtomicBoolean(true) ;
private String result = null ;
public String doAndWait()
{
synchronized(processed) {
doSomethingAsync() ;
processed.wait();
}
return result ;
}
public void doSomethingAsync()
{
...
result="OK";
synchronized(processed) {
processed.notify();
}
}
Related
Suppose there are multiple threads trying to find a value, whichever thread finds it first should send the output to the main thread and all other threads should be terminated.
Example -
public class WorkerThread implements Runnable {
#Override
public void run() {
// some long task here, returns int value
}
}
public class Main {
public static void main(String[] args){
// initialize multiple worker threads here
// then get result from the thread that completes first
}
}
I looked into docs and found invokeAny ExecutorService but this will return the result of any thread that has been completed successfully and not necessarily the first one.
As #Andy Turner said, use a CompletionService:
public static class WorkerThread implements Callable<Integer> {
#Override
public Integer call() throws Exception {
int nextInt = new Random().nextInt(10000);
try {
System.out.println("I will cost " + nextInt + " ms to finish job.--" + Thread.currentThread().getName());
Thread.sleep(nextInt);
} catch (InterruptedException ite) {
System.out.println("I am interrupted.--" + Thread.currentThread().getName());
return -1;
}
System.out.println("I am finish.--" + Thread.currentThread().getName());
return nextInt;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
int nums = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nums);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);
while (nums-- > 0) {
completionService.submit(new WorkerThread());
}
Integer firstValue = completionService.take().get();
System.out.println("FirstValue is " + firstValue);
executorService.shutdownNow();
}
And you can see in output, only one thread will complete the job (Because only call completionService#take once
), other threads will be interrupted and exit
:
I will cost 8943 ms to finish job.--pool-1-thread-1
I will cost 9020 ms to finish job.--pool-1-thread-2
I will cost 5025 ms to finish job.--pool-1-thread-3
I am finish.--pool-1-thread-3
FirstValue is 5025
I am interrupted.--pool-1-thread-1
I am interrupted.--pool-1-thread-2
You can also use CountDownLatch and ExecutorService for achieving this.
Create CountDownLatch object with count = 1.
CountDownLatch latch = new CountDownLatch(1);
Use ExecutorService pool to execute the threads and pass the latch in all the threads.
workerThreadPool.execute(new WorkerThread(latch));
Wait for any thread to complete it's operation.
latch.await();
In the finally block of the thread run, shutdown the latch.
latch.countDown();
As soon as any thread countDown's the latch, the threadpool will stop all the other threads and shutdown.
workerThreadPool.shutdownNow();
The complete example would be below.
import static java.lang.Thread.sleep;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable
{
CountDownLatch _latch;
public WorkerThread(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread1 " + this.toString());
sleep(5000);
}
catch (InterruptedException ex)
{
System.out.println("thread1 interupted");
}
finally
{
System.out.println("Finished1 " + this.toString());
_latch.countDown();
}
}
}
class WorkerThread2 implements Runnable
{
CountDownLatch _latch;
public WorkerThread2(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread2 " + this.toString());
sleep(10000);
}
catch (InterruptedException ex)
{
System.out.println("thread2 interupted");
}
finally
{
System.out.println("Finished2 " + this.toString());
_latch.countDown();
}
}
}
public class Main
{
public static void main(String[] args) throws InterruptedException
{
ExecutorService workerThreadPool = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
workerThreadPool.execute(new WorkerThread(latch));
workerThreadPool.execute(new WorkerThread2(latch));
latch.await();
workerThreadPool.shutdownNow();
}
}
You -could- pass a reference to the Thread where the Thread can send its results. But you'd better follow advice in the other answers and use a better API for this :)
public static void main(//) {
ResultConsumer r = new ResultConsumer();
... create and start worker threads
}
public class WorkerThread implements Runnable {
public WorkerThread ( ResultConsumer r ) {
this.r=r
}
#Override
public void run() {
// some long task here, returns int value
r.sendResult(....)
}
}
I'm new to Java concurrent package and want to try ExecutorService to control the execution time of a thread.
So for a keep running thread MyThread, I want to use ExecutorService and Future class to stop it after 2 seconds.
public class MyThread extends Thread {
public static int count = 0;
#Override
public void run() {
while (true) {
System.out.println(count++);
}
}
}
public static void main(String[] args) throws IOException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
MyThread thread = new MyThread();
FutureTask<String> futureTask = new FutureTask<String>(thread, "success");
try {
executorService.submit(futureTask).get(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
System.out.println("timeout");
e.printStackTrace();
executorService.shutdownNow();
}
}
However, the thread is still keep printing numbers after 2 seconds. How can I control the thread without changing MyThread class itself?
The main purpose of using ExecutorService is to hide how threads are created, reused and in general managed for the programmer.
Instead of creating MyThread, you need to implement a Runnable:
public class MyRunnable implements Runnable {
private int count = 0;
public void run() {
while (true) {
System.out.println(count++);
}
}
}
And, this would be how to use it:
Future<Void> f = executorService.submit(new MyRunnable());
f.get(2, TimeUnit.SECONDS);
Regarding the termination property in the question, the example Runnable is not a good one, because it does not provide an interruptible task. For example, if a sleep operation is added:
public class MyRunnable implements Runnable {
private int count = 0;
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(count++);
try {
Thread.sleep(0, 1);
} catch (InterruptedException x) {
return;
}
}
}
}
Use returned Future object for control.
In a web server i wrote, each request invokes a list of actions. Some of these actions aren't as critical as others, so I would like to run them in a background thread.
Also, since they aren't that important I don't care if one of them fails seldomly, and I don't want them to take up a thread forever, so other threads would be available to process the next batch.
So, I would like to have a thread pool (e.g.: 10 threads) and hand out a thread to each background task like this. Limit each thread to 1 second, and if it doesn't finish by that time, just kill it, and be available for the next task to come in.
How would I go about doing this ?
So far, this is what I have :
public class AsyncCodeRunner {
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
public void Run(Callable<Void> callableCode, int timeout) {
final int threadTimeout = 10;
Future<Void> callableFuture = executor.submit(callableCode);
try {
callableFuture.get(threadTimeout, TimeUnit.SECONDS);
} catch (Exception e) {
logger.Info("Thread was timed out", e);
}
}
}
And I want to use this class like this :
public void processRequest(RequestObject request) {
// do some important processing
// throw some less important processing to background thread
(new AsyncCodeRunner()).Run(new Callable<Void> () {
#Override
public Void call() throws Exception {
// do something...
return null;
}
}, 1); // 1 second timeout
// return result (without waiting for background task)
return;
}
Will this work like I want it to ? Or how should I change it so it would ?
And what happens if I call Run() but there are no available threads in the threadpool to hand out ?
I think your primary problem with this rather elegant idea is that you are only timing out on the get of the Future, you are not actually aborting the process once it times out, you are just giving up waiting for it. The issue becomes even more complex when you realise that you may even time out when the process hasn't even started - it is just still in the queue.
Perhaps something like this would be effective. It does require two threads but a TimerTask thread should consume very little.
public class RunWithTimeout {
public RunWithTimeout(Runnable r, long timeout) {
// Prepare the thread.
final Thread t = new Thread(r);
// Start the timer.
new Timer(true).schedule(new TimerTask() {
#Override
public void run() {
if (t.isAlive()) {
// Abort the thread.
t.interrupt();
}
}
}, timeout * 1000);
// Start the thread.
t.start();
}
}
class WaitAFewSeconds implements Runnable {
final long seconds;
WaitAFewSeconds(long seconds) {
this.seconds = seconds;
}
#Override
public void run() {
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException ie) {
System.out.println("WaitAFewSeconds(" + seconds + ") - Interrupted!");
}
}
}
public void test() {
new RunWithTimeout(new WaitAFewSeconds(5), 3);
new RunWithTimeout(new WaitAFewSeconds(3), 5);
}
Here's an alternative that only uses one extra thread.
public class ThreadKiller implements Runnable {
DelayQueue<WaitForDeath> kill = new DelayQueue<>();
private class WaitForDeath implements Delayed {
final Thread t;
final long finish;
public WaitForDeath(Thread t, long wait) {
this.t = t;
this.finish = System.currentTimeMillis() + wait;
}
#Override
public long getDelay(TimeUnit unit) {
return unit.convert(finish - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
#Override
public int compareTo(Delayed o) {
long itsFinish = ((WaitForDeath) o).finish;
return finish < itsFinish ? -1 : finish == itsFinish ? 0 : 1;
}
}
#Override
public void run() {
while (true) {
try {
WaitForDeath t = kill.take();
if (t.t.isAlive()) {
// Interrupt it.
t.t.interrupt();
}
} catch (InterruptedException ex) {
// Not sure what to do here.
}
}
}
public void registerThread(Thread t, long wait) {
// Post it into the delay queue.
kill.add(new WaitForDeath(t, wait));
}
}
public void test() throws InterruptedException {
// Testing the ThreadKiller.
ThreadKiller killer = new ThreadKiller();
Thread killerThread = new Thread(killer);
killerThread.setDaemon(true);
Thread twoSeconds = new Thread(new WaitAFewSeconds(2));
Thread fourSeconds = new Thread(new WaitAFewSeconds(4));
killer.registerThread(twoSeconds, 5000);
killer.registerThread(fourSeconds, 3000);
killerThread.start();
twoSeconds.start();
fourSeconds.start();
System.out.println("Waiting");
Thread.sleep(10 * 1000);
System.out.println("Finished");
killerThread.interrupt();
}
You need to start timer when the thread runs. Then no thread in waiting state will be killed. Here is the sample from this thread:
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PoolTest {
class TimeOutTask extends TimerTask {
Thread t;
TimeOutTask(Thread t) {
this.t = t;
}
public void run() {
if (t != null && t.isAlive()) {
t.interrupt();
}
}
}
class MyRunnable implements Runnable {
Timer timer = new Timer(true);
public void run() {
timer.schedule(new TimeOutTask(Thread.currentThread()), 1000);
try {
System.out.println("MyRunnable...");
Thread.sleep(10000);
} catch (InterruptedException ie) {
System.out.println("MyRunnable error...");
ie.printStackTrace();
}
}
}
public static void main(String args[]) {
new PoolTest();
}
public PoolTest() {
try {
ExecutorService pe = Executors.newFixedThreadPool(3);
pe.execute(new MyRunnable());
} catch (Exception e) {
e.printStackTrace();
}
}
}
I am new to the Threading, so if please give me an advice for my case.
I would like create a new thread to do something and I don't care this thread can do complete or not.
I intend to use ExecutorCompletionService to do my job but this class is not suitable for me. It must call take or poll to drain a queue to avoid memory leak. So, this means I must wait until the thread complete. I read this from this question
This is the current code
ExecutorService executor = Executors.newCachedThreadPool();
CompletionService<Entity> completion = new ExecutorCompletionService<>(executor);
DoSomeThingClass doSomething = getInstance();
completion.submit(doSomething);
executor.shutdown();
// Continue to do other job and I don't care whenever doSomeThing is complete.
// However when doSomeThing finish, I don't need to do anything to avoid memory leak
For that reason, please give me an approach for my case and some skeleton code for example.
Thank you so much
You can mark this thread as "Daemon". And when your main thread completed, your app will exit.
public static void main(String[] args)
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch(InterruptedException e) {}
System.out.println("Thread 2 is finished");
}
});
t.setDaemon(true);
t.start();
System.out.println("Thread 1 is finished");
}
You can use Spring TaskExecutor, it is very useful to raise a thread to run a task.
import org.springframework.core.task.TaskExecutor;
public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public MessagePrinterTask(String message) {
this.message = message;
}
public void run() {
System.out.println(message);
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}
You can check Spring Task Execution documentation here:
http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html
Along with you code your Future concept
Future ft=completion.submit(doSomething);
ft.get(timeOut, TimeUnit.MILLISECONDS);
here you can specify Time to execute Thread if it fail to get execute thread get kill(not 100% sure)means it try to interrupt the thread and try to kill
I can resolve my problem as the following code
public static void main(
String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
} finally {
System.out.println("Thread 2 is finished");
}
}
});
executor.shutdown();
System.out.println("Thread 1 is finished");
}
I am new to threading and semaphors, and I have some problem in synchronizing threads. For example, in the following code I want to do a pretty simple thing. To let one thread run, while other waits. For example, if it starts with the first thread, I want the second to wait for the first one to finish and then start. I really don't know what am I doing wrong.
Here is the code :
import java.io.*;
import java.util.concurrent.Semaphore;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Semaphore binaren = new Semaphore(1);
Runnable t1 = new T2(binaren);
Thread a = new Thread(t1);
Thread a2 = new T1(binaren);
System.out.println(binaren.availablePermits());
a.start();
a2.start();
}
}
class Work {
private static int a = 4;
public synchronized static void QQR(String s1)
{
for(int i=0;i<100;i++)
System.out.println(s1+" : "+(a++));
}
}
class T1 extends Thread
{
Semaphore sem;
public T1(Semaphore s1)
{
sem=s1;
}
public void run()
{
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T1");
sem.release();
notifyAll();
}
}
}
class T2 extends Thread
{
Semaphore sem;
public T2(Semaphore s1)
{
sem=s1;
}
#Override
public void run() {
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T2");
sem.release();
notifyAll();
}
}
}
The problem is that notify and notifyAll only wake up threads holding locks on the monitor being notified. But the t1 and t2 instances are waiting on themselves and are never awoken. You can have them wait on the semaphore for this simple test or introduce a new shared object to see how it works.
Use
sem.wait();
and
sem.notifyAll();
You can use Thread.join() on the first thread so that second thread will wait till the execution of this instance is not completed.