Java 8 Completable Future - parallel execution - java

I'm testing how CompletableFuture works. I am interested in how to execute tasks in parallel:
try {
CompletableFuture one = CompletableFuture.runAsync(() -> {
throw new RuntimeException("error");
});
CompletableFuture two = CompletableFuture.runAsync(() -> System.out.println("2"));
CompletableFuture three = CompletableFuture.runAsync(() -> System.out.println("3"));
CompletableFuture all = CompletableFuture.allOf(one, two, three);
all.get();
} catch (InterruptedException e) {
System.out.println(e);
} catch (ExecutionException e) {
System.out.println(e);
}
In this case they will be executed all.
1. Is it possible to interrupt all running threads when threre is an exception in one of them?
2. When this code is inside a class' method which can be invoked from different threads will it be threadsafe?

1.Is it possible to interrupt all running threads when there is an exception in one of them?
Yes, it is possible. All threads should have an access to common object which state can be changed and read by other threads. It can be for example AtomicInteger. See below example:
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
public class Dates {
public static void main(String[] args) throws Exception {
try {
AtomicInteger excCounter = new AtomicInteger(0);
CompletableFuture one = CompletableFuture.runAsync(new ExcRunnable(excCounter));
CompletableFuture two = CompletableFuture.runAsync(new PrintRunnable("2", excCounter));
CompletableFuture three = CompletableFuture.runAsync(new PrintRunnable("3", excCounter));
CompletableFuture all = CompletableFuture.allOf(one, two, three);
all.get();
} catch (InterruptedException | ExecutionException e) {
System.out.println(e);
}
}
}
class ExcRunnable implements Runnable {
private final AtomicInteger excCounter;
public ExcRunnable(AtomicInteger excCounter) {
this.excCounter = excCounter;
}
#Override
public void run() {
Random random = new Random();
int millis = (int) (random.nextDouble() * 5000);
System.out.println("Wait " + millis);
Threads.sleep(450);
// Inform another threads that exc occurred
excCounter.incrementAndGet();
throw new RuntimeException("error");
}
}
class PrintRunnable implements Runnable {
private final String name;
private final AtomicInteger excCounter;
public PrintRunnable(String name, AtomicInteger excCounter) {
this.name = name;
this.excCounter = excCounter;
}
#Override
public void run() {
int counter = 10;
while (counter-- > 0 && excCounter.get() == 0) {
System.out.println(name);
Threads.sleep(450);
}
}
}
class Threads {
static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
We have 3 tasks: two which prints it's name and one which throws exception after some time. Before exception is thrown counter is incremented to inform other tasks that one of them failed and they should finish executions. Print jobs are checking this counter and in case condition is not met they finish it's job. When you comment excCounter.incrementAndGet(); line other tasks finish theirs job without knowing that one of them thrown exception.
When this code is inside a class' method which can be invoked from different threads will it be thread safe?
Take a look on the definition of thread safety. For example, assume that print tasks increment common counter with every printed line. If counter is primitive int it is not thread safety because counter value could be replaced. But if you use AtomicInteger it is thread safety because AtomicInteger is thread safety.

1
if any of your async task throw exception, all.get() will throw exception.
That means, you can cancel all CF in catch clause.
But, your async tasks need to be interrupt friendly i.e. check for interrupt flag periodic or handle InterruptedException and return early.
Task cancellation should always be handled using interrupt mechanism
2
All the reference variables mentioned by you are local, so there is no need to worry about thread safety. Local variables are always thread safe.

Related

Continuously submitting Runnable tasks to ExecutorService until work is done, getting java.util.concurrent.RejectedExecutionException

My multi-threaded class is supposed to carry out three operations – operation1, operation2, and operation3 – on a number of objects of the class ClassA, where each type of operation is dependant on the earlier operation. For this, I have tried to implement the producer-consumer pattern using a number of BlockingQueues and an ExecutorService.
final ExecutorService executor = ForkJoinPool.commonPool();
final BlockingQueue<ClassA> operationOneQueue = new ArrayBlockingQueue<>(NO_OF_CLASS_A_OBJECTS);
final BlockingQueue<ClassA> operationTwoQueue = new ArrayBlockingQueue<>(NO_OF_CLASS_A_OBJECTS);
final BlockingQueue<ClassA> operationThreeQueue = new ArrayBlockingQueue<>(NO_OF_CLASS_A_OBJECTS);
final BlockingQueue<ClassA> resultQueue = new ArrayBlockingQueue<>(NO_OF_CLASS_A_OBJECTS);
The operations are implemented like this:
void doOperationOne() throws InterruptedException {
ClassA objectA = operationOneQueue.take();
objectA.operationOne();
operationTwoQueue.put(objectA);
}
where each type of operation has its own corresponding method, with its "own" in-queue and out-queue. Each operation method calls the appropriate method on the ClassA object. The method doOperationThree puts ClassA objects in the resultQueue, meaning they have been completely processed.
First, I fill the operationOneQueue with all ClassA objects that are to be operated on. Then, I try to assign executable tasks to the ExecutorService like this:
while (resultQueue.size() < NO_OF_CLASS_A_OBJECTS) {
executor.execute(() -> {
try {
doOperationOne();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
executor.execute(() -> {
try {
doOperationTwo();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
executor.execute(() -> {
try {
doOperationThree();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown();
Running my program, I get a java.util.concurrent.RejectedExecutionException.
Operation1: ClassA object 0
Operation2: ClassA object 0
Operation1: ClassA object 1
Operation3: ClassA object 0
....
Operation1: ClassA object 46
Operation2: ClassA object 45
Operation3: ClassA object 45
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Queue capacity exceeded
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.growArray(ForkJoinPool.java:912)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.lockedPush(ForkJoinPool.java:867)
at java.base/java.util.concurrent.ForkJoinPool.externalPush(ForkJoinPool.java:1911)
at java.base/java.util.concurrent.ForkJoinPool.externalSubmit(ForkJoinPool.java:1930)
at java.base/java.util.concurrent.ForkJoinPool.execute(ForkJoinPool.java:2462)
at concurrent.operations.Program1.main(Program1.java:96)
What am I doing wrong? How can I achieve this without over-saturating the thread pool?
Edit: Full disclosure – this is homework with some requirements. 1. I must use ForkJoinPool.commonPool() and must not set the number of threads myself, 2. I must use the consumer-producer pattern, and 3. I must not modify ClassA.
I really like doing concurrent stuff, so I did try writing it. I did use CompletableFuture which a) does run in the ForkJoinPool.commonPool by default and b) makes the actual processing really easy:
while (true) {
final ClassA nextOperation = queue.take();
CompletableFuture.runAsync(nextOperation::operationOne)
.thenRun(nextOperation::operationTwo)
.thenRun(nextOperation::operationThree)
.thenRun(() -> resultQueue.add(nextOperation));
}
This will take ClassA objects from the queue and execute all their operations concurrently, but in order.
You did leave out where the tasks are coming from, and whether you need the consumer to terminate. Generally you don't want to, and it does make matters a bit more complicated.
private static final int COUNT = 10;
private static final Random RANDOM = new Random();
public static void main(String[] args) throws ExecutionException, InterruptedException {
BlockingQueue<ClassA> runnables = new ArrayBlockingQueue<>(COUNT);
BlockingQueue<ClassA> finished = new ArrayBlockingQueue<>(COUNT);
// start producer
ExecutorService createTaskExecutor = Executors.newSingleThreadExecutor();
createTaskExecutor.submit(() -> fillQueue(runnables));
// wait for all consumer tasks to finish
while (finished.size() != COUNT) {
try {
// we need to poll instead of waiting forever
// because the last tasks might still be running
// while there are no others to add anymore
// so we need to check again if all have finished in the meantime
final ClassA nextOperation = runnables.poll(2, TimeUnit.SECONDS);
if (nextOperation != null) {
CompletableFuture.runAsync(nextOperation::operationOne)
.thenRun(nextOperation::operationTwo)
.thenRun(nextOperation::operationThree)
.thenRun(() -> finished.add(nextOperation));
}
} catch (InterruptedException e) {
System.err.println("exception while retrieving next operation");
// we will actually need to terminate now, or probably never will
throw e;
}
}
System.out.printf("finished tasks (%d):%n", finished.size());
for (ClassA classA : finished) {
System.out.printf("finished task %d%n", classA.designator);
}
createTaskExecutor.shutdown();
}
private static void fillQueue(BlockingQueue<ClassA> runnables) {
// start thread filling the queue at random
for (int i = 0; i < COUNT; i++) {
runnables.add(new ClassA(i));
try {
Thread.sleep(RANDOM.nextInt(1_000));
} catch (InterruptedException e) {
System.err.println("failed to add runnable");
}
}
}
Since you didn't provide ClassA, I used this one. It contains an identifier so you can track which is running at what time.
class ClassA {
private static final Random RANDOM = new Random();
public final int designator;
public ClassA(int i) {
designator = i;
}
public void operationOne() {
System.out.printf("%d: operation 1%n", designator);
sleep();
}
public void operationTwo() {
System.out.printf("%d: operation 2%n", designator);
sleep();
}
public void operationThree() {
System.out.printf("%d: operation 3%n", designator);
sleep();
}
private static void sleep() {
try {
Thread.sleep(RANDOM.nextInt(5_000));
} catch (InterruptedException e) {
System.err.println("interrupted while executing task");
}
}
}

Java execute 3 methods at same time inside custom method and grab values from run methods

I would like to execute 3 methods at same time in Java (obviously I need threads), and that I would like to execute not in separate class and not in my main method, but in my custom method. Can it be done?
I have find this piece of code - Execute Multiple Methods Simaltaneously Using Thread In Java
and reused best marked answer for my example, with parameters that I have:
private void fetchData() {
boolean t1_run = true;
boolean t2_run = true;
boolean t3_run = true;
int SLEEP_TIME = 100;//Configurable.
Thread thread1 = new Thread() {
public void run() {
while (t1_run)
{
try
{
subjects = new BeanItemContainer<KltSubject>(KltSubject.class, clijentService.getSubjecteByType(Integer.valueOf(creditor)));
Thread.sleep(SLEEP_TIME);//So that other thread also get the chance to execute.
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
};
Thread thread2 = new Thread() {
public void run() {
while (t2_run)
{
try
{
programs = new BeanItemContainer<Program>(Program.class, creditService.getAllPrograms());
Thread.sleep(SLEEP_TIME);//So that other thread also get the chance to execute.
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
};
Thread thread3 = new Thread() {
public void run() {
while (t3_run)
{
try
{
credits = new BeanItemContainer<CreditExt>(CreditExt.class, creditService.getAllCredits());
Thread.sleep(SLEEP_TIME);//So that other thread also get the chance to execute.
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
};
thread1.start();
thread2.start();
thread3.start();
}
Now, before I've put my variables in threads (variables named: subjects, programs and credits), I could easily get their values (these variables you can see in above code in this example in their run methods, but are defined outside my fetchData() method and are visible).
After setting code like this, and executing it, I recieve null pointer exception because obviously varaibles are not seen any more after threads are executed. How to get that values after execution in threads?
P.S. can this code be written more elegantly, with less lines of code? If Java 8 (or Java 7) can done it - show me please how?
Use advanced Threading API : ExecutorService invokeAll()
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException
Executes the given tasks, returning a list of Futures holding their status and results when all complete. Future.isDone() is true for each element of the returned list. Note that a completed task could have terminated either normally or by throwing an exception. The results of this method are undefined if the given collection is modified while this operation is in progress.
Sample code:
ExecutorService service = Executors.newFixedThreadPool(3);
List<MyCallable> futureList = new ArrayList<MyCallable>();
MyCallable1 myCallable1 = new MyCallable1(); // your first thread
MyCallable2 myCallable2 = new MyCallable2(); // your second thread
MyCallable3 myCallable1 = new MyCallable3(); // your third thread
futureList.add(myCallable1);
futureList.add(myCallable2);
futureList.add(myCallable3);
System.out.println("Start");
try{
List<Future<Long>> futures = service.invokeAll(futureList);
for(Future<Long> future : futures){
try{
System.out.println("future.isDone = " + future.isDone());
System.out.println("future: call ="+future.get());
}
catch(Exception err1){
err1.printStackTrace();
}
}
}catch(Exception err){
err.printStackTrace();
}
service.shutdown();
You can have a look into few more examples in this article
You can use join() to wait for the threads to finish.
eg:
thread1.join();
thread2.join();
thread3.join();
when all the threads are done, the variables shouldn't be null.
Making this more compact depends on what exactly you're trying to do. Here is an example:
private List<Result> fetchData() {
final List<Result> results = new ArrayList<Result>();
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i < 3; i++){
Thread t = new Thread() {
public void run() {
Result result = getResult();
synchronized(results) {
results.add(result);
}
}
};
t.start();
threads.add(t);
}
for(Thread t:threads) {
t.join();
}
return results;
}
You can simply use a CompletableFuture:
CompletableFuture<BeanItemContainer<KltSubject>> job1 = CompletableFuture.supplyAsync(() ->
new BeanItemContainer<>(KltSubject.class, clijentService.getSubjecteByType(creditor)));
CompletableFuture<BeanItemContainer<Program>> job2 = CompletableFuture.supplyAsync(() ->
new BeanItemContainer<>(Program.class, creditService.getAllPrograms()));
CompletableFuture<BeanItemContainer<CreditExt>> job3 = CompletableFuture.supplyAsync(() ->
new BeanItemContainer<>(CreditExt.class, creditService.getAllCredits()));
subjects = job1.join();
programs = job2.join();
credits = job3.join();
The method supplyAsync will initiate the asynchronous computation of a value and join will return the computed value, waiting, if necessary. But if all three actions imply querying the same database, it might be possible, that you don’t gain any performance advantage as the database may be the limiting factor.

Looking for a solid explanation on how aquire and release work with semaphores to sync threads

I am trying to manipulate this program to print ":---)))))" repeatedly.
I understand that a semaphore is a way of controlling threads, and acquire essentially acquires a permit (reads) and release returns a permit back to the semaphore. (writes)
I've tried manipulating the number of permits when initializing the semaphores, but I am not understanding how to sync them together because I can't figure out how exactly the semaphores operate with how they acquire and release.
I am looking for a helpful explanation that pertains to Java in the context of only using semaphores, acquire and release and how they work together to properly put the threads "in sync"
import java.lang.Thread;
import java.util.concurrent.*;
public class ThreadSync {
private static boolean runFlag = true;
private static Semaphore canPrintC = new Semaphore(1);
private static Semaphore canPrintD = new Semaphore(0);
private static Semaphore canPrintP = new Semaphore(0);
public static void main(String [] args) {
// Create and start each runnable
Runnable task1 = new TaskPrintC();
Runnable task2 = new TaskPrintD();
Runnable task3 = new TaskPrintP();
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
Thread thread3 = new Thread(task3);
thread1.start();
thread2.start();
thread3.start();
// Let them run for 500 ms
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
runFlag = false;
thread3.interrupt();
thread2.interrupt();
thread1.interrupt();
}
public static class TaskPrintC implements Runnable {
public void run() {
while (runFlag) {
try {
canPrintC.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%s", ":");
canPrintD.release();
}
}
}
public static class TaskPrintD implements Runnable {
public void run() {
while (runFlag) {
try {
canPrintD.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%s", "-");
canPrintP.release();
}
}
}
public static class TaskPrintP implements Runnable {
public void run() {
while (runFlag) {
try {
canPrintP.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf("%s", ")");
canPrintC.release();
}
}
}
}
Threads execute tasks and semaphores can help you to let tasks (or runnable objects) know each other's state (e.g. task A waits for input from task B and task B can signal task A that input is available). The difference between a task and a thread is important.
To stress this point, I have taken your example and made one runnable class that performs the task of printing a character a number of times (configured via variables in the constructor). To mimic the serialized behavior (tasks run after each other), the runnable is also aware of the next runnable that should perform the print task.
To complete the example I also ensured that the thread that is executing the main-method is aware of when the tasks have completed, so that the program stops at the proper time. A CountDownLatch is used in this case (a CountDownLatch is a very simple variation of a Semaphore).
The example below might be a bit hard to understand, but it shows some good practices (re-use code, using a stop-flag instead of interrupt, use an executor to run tasks, cleanup and stop tasks in case of error). It also shows how Semaphores can orchestrate the execution of tasks.
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ChainedSemaphoreTasks {
// amount of times chained tasks are executed.
static int MAX_CHAINED_LOOPS = 3;
// helper to let main-thread know when chained loops have been executed.
final static CountDownLatch MAX_LOOPS_REACHED = new CountDownLatch(1);
public static void main(String[] args) {
String printChars = ":-)";
int[] repeatChars = { 1, 3, 5};
List<ChainedTask> tasks = buildTasks(printChars, repeatChars);
ExecutorService executor = Executors.newCachedThreadPool();
for (ChainedTask task : tasks) {
executor.execute(task);
}
try {
// Trigger first task to start running.
tasks.get(0).triggerPrintTask();
// wait for loop to complete, but not too long.
if (!MAX_LOOPS_REACHED.await(5000L, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Chained tasks loop did not complete within timeout.");
}
long waitStart = System.currentTimeMillis();
executor.shutdown();
if (executor.awaitTermination(1000L, TimeUnit.MILLISECONDS)) {
System.out.println("All tasks stopped within " + (System.currentTimeMillis() - waitStart) + " ms.");
} else {
throw new RuntimeException("Not all chained tasks stopped within timeout.");
}
} catch (Exception e) {
e.printStackTrace();
// cleanup
try {
tasks.get(0).stop();
} catch (Exception e2) {
e2.printStackTrace();
}
executor.shutdownNow();
}
}
static List<ChainedTask> buildTasks(String printChars, int[] repeatChars) {
List<ChainedTask> tasks = new ArrayList<ChainedTask>();
int maxTasks = printChars.length();
if (maxTasks != repeatChars.length) {
throw new IllegalArgumentException("Amount of repeats per pritn character must match amount of characters.");
}
for (int i = 0; i < maxTasks; i++) {
ChainedTask task = new ChainedTask(printChars.charAt(i), repeatChars[i]);
tasks.add(task);
if (i > 0) {
tasks.get(i - 1).setNextTask(task);
}
}
// make last task trigger first task - creates an endless loop.
tasks.get(maxTasks - 1).setNextTask(tasks.get(0));
tasks.get(maxTasks - 1).setLastTask(true);
return tasks;
}
static AtomicInteger chainedLoopsCount = new AtomicInteger();
static class ChainedTask implements Runnable {
// Semaphore to trigger execution
Semaphore performTask = new Semaphore(0);
// If stop is true, task must finish.
// stop must be volatile to ensure updated value is always visible.
volatile boolean stop = false;
// The last task is responsible for stopping execution
boolean lastTask;
// The next task to run after this task.
ChainedTask nextTask;
char printChar;
int repeatAmount;
ChainedTask(char printChar, int repeatAmount) {
this.printChar = printChar;
this.repeatAmount = repeatAmount;
System.out.println("Created " + printChar + " / " + repeatAmount);
}
void triggerPrintTask() {
performTask.release(repeatAmount);
}
void stop() {
// first indicate to stop
stop = true;
// then release a permit to pickup the stop sign.
performTask.release();
// also stop next task, unless this is the last task
if (!isLastTask()) {
getNextTask().stop();
}
}
#Override
public void run() {
try {
while (!stop) {
runTask();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Stopped " + printChar + " / " + repeatAmount);
}
void runTask() throws Exception {
// wait for our turn
performTask.acquire();
// must check 'stop' after getting permit, see the stop-method:
// first stop is set to true and then a permit is released.
if (stop) {
return;
}
// print text for loop-amount
do {
System.out.print(printChar);
} while (performTask.tryAcquire());
if (isLastTask()) {
System.out.println();
// check if we should stop
if (chainedLoopsCount.incrementAndGet() >= MAX_CHAINED_LOOPS) {
// since this is the last task, the next task is the first task.
// stopping the first task will call the stop-method on all tasks, including this one.
getNextTask().stop();
// signal main-thread we are done.
MAX_LOOPS_REACHED.countDown();
}
// Sleep for a long time to test what happens when last task hangs.
// Should trigger the "cleanup" code in the main method.
// Thread.sleep(10000);
}
// trigger next chained task to run
// this has no effect if next chained task was stopped
getNextTask().triggerPrintTask();
}
void setNextTask(ChainedTask nextTask) {
this.nextTask = nextTask;
}
ChainedTask getNextTask() {
return nextTask;
}
void setLastTask(boolean lastTask) {
this.lastTask = lastTask;
}
boolean isLastTask() {
return lastTask;
}
}
}
Semaphore – to solve Producer/Consumer problem
A high level explanation of semaphore.
A semaphore contains a count indicating whether a resource is locked or available. Semaphore is a signaling mechanism (“I am done, you can carry on.”). The resource itself may not be thread safe.
Producer
semObject.Post(); // Send the signal
Increase the semaphore count by 1. If a thread is waiting on the
specified semaphore, it is awakened.[1]
Consumer
semObject.Wait(); // Wait for the signal
When the semaphore count is zero, the thread calling this function
will wait for the semaphore. When the semaphore count is nonzero, the
count will be decremented by 1 and the thread calling this function
will continue.[1]
Reference
[1] Massa, Anthony J., Embedded software development with eCos, Pearson Education, Inc., 2002

Java: notify main class when all threads in threadpool are finished / same instance of object in different threads

How do I notify my main class which instantiates a ThreadPoolExecutor when all threads within the ThreadPoolExecutor are completed?
ThreadPoolExecutor threadPool = null;
ThreadClass threadclass1;
ThreadClass threadclass2;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(maxPoolSize);
puclic MyClass(){
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
threadClass1 = new ThreadClass;
threadClass2 = new ThreadClass;
threadPool.execute(threadClass1);
threadPool.execute(threadClass2);
//Now I would like to do something until the threadPool is done working
//The threads fill a ConcurrentLinkedQueueand I would like to poll
//the queue as it gets filled by the threads and output
//it to XML via JAX-RS
}
EDIT 1
Wile my threads fetch data from somewhere and fill this information into a ConcurrentLinkedQueue I basically would like to perform some action in MyClass to update the XML output with the results. When all threads are terminated I would like to return true to the JAX-RS webservice which instantiated MyClass so the webservice knows all data has been fetched and it can now display the final XML file
EDIT 2
I am passing a Queue to threads so they can add items to the queue. When one driver is done adding items to the articleQueue I want to perform an action within my main class, polling the entity from the Queue and handing it over to the response object to display it in some way.
When I pass the queue to the threads, are they working with the same object or with a "copy" of the object so that changes within the thread do not effect the main object? That is not the behavior I want. When I check the size of the articleQueue within the Driver it is 18, the size of the articleQueue in the DriverController is 0.
Is there a nicer way to react when a thread has added something to the queue other than my while loop? How do I have to modify my code to acces the same object within different classes?
DriverController
public class DriverController {
Queue<Article> articleQueue;
ThreadPoolExecutor threadPool = null;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
maxPoolSize);
public DriverController(Response response) {
articleQueue = new ConcurrentLinkedQueue<Article>();
threadPool = new ThreadPoolExecutor();
Driver driver = new Driver(this.articleQueue);
threadPool.execute(driver);
// More drivers would be executed here which add to the queue
while (threadPool.getActiveCount() > 0) {
// this.articleQueue.size() gives back 0 here ... why?
if(articleQueue.size()>0){
response.addArticle(articleQueue.poll());
}
}
}
}
Driver
public class Driver implements Runnable{
private Queue<Article> articleQueue;
public DriverAlliedElectronics(Queue articleQueue) {
this.articleQueue = articleQueue;
}
public boolean getData() {
// Here would be the code where the article is created ...
this.articleQueue.offer(article);
return true;
}
public void run() {
this.getData();
// this.articleQueue.size() gives back 18 here ...
}
}
You should try to use following snippet
//Now I would like to wait until the threadPool is done working
threadPool.shutdown();
while (!threadPool.isTerminated()) {
try {
threadPool.awaitTermination(10, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Maybe a ExecutorCompletionService might be the right thing for you:
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html
Example from the link above:
void solve(Executor e, Collection<Callable<Result>> solvers)
throws InterruptedException, ExecutionException {
CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
if (r != null)
use(r);
}
}
Instead of using execute you should use submit. This will return a Future instance on which you can wait for the task(s) to complete. That way you don't need polling or shutting down the pool.
I don't think there's a way to do this explicitly. You could poll the getCompletedTaskCount() to wait for that to become zero.
Why not collect the Future objects returned upon submission and check for all of those being completed ? Simply call get() on each one in turn. Since that call blocks you'll simply wait for each in turn and gradually fall through the set until you've waited on each on.
Alternatively you could submit the threads, and call shutdown() on the executor. That way, the submitted tasks will be executed, and then the terminated() method is called. If you override this then you'll get a callback once all tasks are completed (you couldn't use that executor again, obviously).
Judging from the reference documentation you have a few options:
ThreadPoolExecutor threadPool = null;
ThreadClass threadclass1;
ThreadClass threadclass2;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(maxPoolSize);
puclic MyClass(){
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
threadClass1 = new ThreadClass;
threadClass2 = new ThreadClass;
threadPool.execute(threadClass1);
threadPool.execute(threadClass2);
//Now I would like to wait until the threadPool is done working
//Option 1: shutdown() and awaitTermination()
threadPool.shutDown();
try {
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
}
catch (InterruptedException e) {
e.printStackTrace();
}
//Option 2: getActiveCount()
while (threadPool.getActiveCount() > 0) {
try {
Thread.sleep(1000);
}
catch (InterruptedException ignored) {}
}
//Option 3: getCompletedTaskCount()
while (threadPool.getCompletedTaskCount() < totalNumTasks) {
try {
Thread.sleep(1000);
}
catch (InterruptedException ignored) {}
}
}
All things considered, I think shutdown() and awaitTermination() is the best option of the three.
I think you're overengineering things a bit. You don't really care about the threads or the thread pool, and rightly so. Java provides nice abstractions so that you don't have to. You just need to know when your tasks are complete, and methods exist for that. Just submit your jobs, and wait for the futures to say they're done. If you really want to know as soon as a single task completes, you can watch all the futures and take action as soon as any one is finished. If not and you only care that everything is finished, you can remove some complexity from the code I'm about to post. Try this on for size (note MultithreadedJaxrsResource is executable):
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.*;
import java.util.concurrent.*;
#Path("foo")
public class MultithreadedJaxrsResource {
private ExecutorService executorService;
public MultithreadedJaxrsResource(ExecutorService executorService) {
this.executorService = executorService;
}
#GET
#Produces(MediaType.APPLICATION_XML)
public AllMyArticles getStuff() {
List<Future<Article>> futures = new ArrayList<Future<Article>>();
// Submit all the tasks to run
for (int i = 0; i < 10; i++) {
futures.add(executorService.submit(new Driver(i + 1)));
}
AllMyArticles articles = new AllMyArticles();
// Wait for all tasks to finish
// If you only care that everything is done and not about seeing
// when each one finishes, this outer do/while can go away, and
// you only need a single for loop to wait on each future.
boolean allDone;
do {
allDone = true;
Iterator<Future<Article>> futureIterator = futures.iterator();
while (futureIterator.hasNext()) {
Future<Article> future = futureIterator.next();
if (future.isDone()) {
try {
articles.articles.add(future.get());
futureIterator.remove();
} catch (InterruptedException e) {
// thread was interrupted. don't do that.
throw new IllegalStateException("broken", e);
} catch (ExecutionException e) {
// execution of the Callable failed with an
// exception. check it out.
throw new IllegalStateException("broken", e);
}
} else {
allDone = false;
}
}
} while (!allDone);
return articles;
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
AllMyArticles stuff =
new MultithreadedJaxrsResource(executorService).getStuff();
System.out.println(stuff.articles);
executorService.shutdown();
}
}
class Driver implements Callable<Article> {
private int i; // Just to differentiate the instances
public Driver(int i) {
this.i = i;
}
public Article call() {
// Simulate taking some time for each call
try {
Thread.sleep(1000 / i);
} catch (InterruptedException e) {
System.err.println("oops");
}
return new Article(i);
}
}
class AllMyArticles {
public final List<Article> articles = new ArrayList<Article>();
}
class Article {
public final int i;
public Article(int i) {
this.i = i;
}
#Override
public String toString() {
return "Article{" +
"i=" + i +
'}';
}
}
Done that way, you can plainly see that the tasks are returned in the order they complete, as the last task finishes first thanks to sleeping the shortest time. If you don't care about completion order and just want to wait for all to finish, the loop becomes much simpler:
for (Future<Article> future : futures) {
try {
articles.articles.add(future.get());
} catch (InterruptedException e) {
// thread was interrupted. don't do that.
throw new IllegalStateException("broken", e);
} catch (ExecutionException e) {
// execution of the Callable failed with an exception. check it out.
throw new IllegalStateException("broken", e);
}
}

How do I call some blocking method with a timeout in Java?

Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.
You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.
You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
See also Guava's TimeLimiter which uses an Executor behind the scenes.
It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps
There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time
I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}
Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}
You need a circuit breaker implementation like the one present in the failsafe project on GitHub.
Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.
Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.

Categories