I have 3 FutureTask<T> Objects. I want that they are processed asynchronously. However, as soon as one of the FutureTasks' get() methods doesn't return null I want to continue i.e my method (wrapper) returns and doesn't wait until the other two FutureTasks are processed.
I thought about something like:
private File wrapper(final File file) {
ExecutorService executors = Executors.newCachedThreadPool();
File returnFile;
FutureTask<File> normal= ...
FutureTask<File> medium=...
FutureTask<File> huge=...
executors.execute(normal);
executors.execute(medium);
executors.execute(huge);
try {
if((returnFile=normal.get()) != null ||
(returnFile=medium.get()) != null ||
(returnFile=huge.get()) != null)
return returnFile;
} catch(ExecutionException | InterruptedException e) { }
}
I'm not sure how to capture the exceptions (thrown by the get()) in a proper way because I assume they will be thrown since I just return without waiting for the other two tasks to be completed. Moreover I've doubts that the code will work like intended. I feel that I'm close to the solution but missing something.
May I suggest to check for FutureTask::isDone?
Would be something like this then:
while(true) {
if (normal.isDone()) {
return normal.get();
}
if (medium.isDone()) {
return medium.get();
}
if (huge.isDone()) {
return huge.get();
}
}
EDIT:
You could cancel the other tasks as soon as you have one result at hand.
Using FutureTask::get is not what you look for as it would most likely always return the result of normal.get() because the documentation already states that:
Waits if necessary for the computation to complete, and then retrieves
its result.
To clarify the above:
If you use FutureTask::get the first FutureTask you call get on will most likely block and wait until a result is available to return.
EDIT2:
Wrap that loop into a new Runnable, executed by the ExecutorService, passing the first result available to another method or implement a Callback and there's no more busy waiting.
I had an idea to design it using BlockingQueue. You extend your tasks with done method submitting results into BlockinQueue and, once client received first result, it cancels other tasks. On the other hand, experts suggest using ExecutorCompletionService instead. It seems to serialize results imself and has all appropriate examples.
Related
SomeLibrary lib = new SomeLibrary();
lib.doSomethingAsync(); // some function from a library I got and what it does is print 1-5 asynchronously
System.out.println("Done");
// output
// Done
// 1
// 2
// 3
// 4
// 5
I want to be clear that I didn't make the doSomethingAsync() function and it's out of my ability to change it. I want to find a way to block this async function and print Done after the numbers 1 to 5 because as you see Done is being instantly printed. Is there a way to do this in Java?
You can use CountDownLatch as follow:
final CountDownLatch wait = new CountDownLatch(1);
SomeLibrary lib = new SomeLibrary(wait);
lib.doSomethingAsync(); // some function from a library I got and what it does is print 1-5 asynchronously
//NOTE in the doSomethingAsync, you must call wait.countDown() before return
wait.await(); //-> it wait in here until wait.countDown() is called.
System.out.println("Done");
In Constructor SomeLibrary :
private CountDownLatch wait;
public ScannerTest(CountDownLatch _wait) {
this.wait = _wait;
}
In method doSomethingAsync():
public void doSomethingAsync(){
//TODO something
...
this.wait.countDown();
return;
}
This is achieved in a couple of ways in standard libraries :-
Completion Callback
Clients can often provider function to be invoked after the async task is complete. This function usually receives some information regarding the work done as it's input.
Future.get()
Async functions return Future for client synchronization. You can read more about them here.
Do check if any of these options are available (perhaps, an overloaded version ?_ in the method you wish to invoke. It is not too uncommon for libraries to include both sync and async version of some business logic so you could search for that too.
I have 3 methods and they're being called from the front end. You can only call a function once you have called the previous function, but don't necessarily need to call all of them. So you may call either just f1, or f1->f2 or f1->f2->f3.
My problem is that on the front end you can click on a function, before the previous one has even stopped running. I need each function to finish before the next function starts running.
What I'm doing at the moment, which works, is pausing the execution until the end of the previous function, but I'd like for a nicer answer:
f1 {
ready1=false
...
ready1=true }
f2 {
ready2=false
while (!ready1) {Thread.sleep(250);}
...
ready2=true }
f3 {
while (!ready2) {Thread.sleep(250);}
...
}
Is there an easy way to do this?
It sounds like you're using a web framework, so maybe include the framework, and it will have some built in tools. One example is to use the built in java tools.
class NoLookingBack{
CountDownLatch latchB = new CountDownLatch(1);
public void methodA(){
//do work.
latchB.countDown();
}
public void methodB(){
try{
latchB.await();
} catch(InterruptException e){
//do something or declare this method throws.
return;
}
}
}
I think this shows how more methods could be included by adding more latches when necessary.
Your example is flawed, and so is this solution. What if methodA fails, then methodB will block forever. The latch gives you the power to use a timeout value, then you can use a response that indicates a failure.
I have the below snippet of code, designed to check if a message was sent to a phone number:
public static boolean checkMessages(long sendTime, String phone) {
boolean gotMessage = false;
while (!gotMessage) {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
gotMessage = MessageHandler.getResponse(sendTime, phone);
}
return gotMessage;
}
This code itself is called through a CompletableFuture, so it can run in parallel with another check. If neither check is satisfied within a certain amount of time, both will expire.
Now, according to my IDE and this site, using Thread.sleep() is bad for a number of reasons, so I'd like to remove it from my code somehow.
Is there a way to do this such that this method will only ever return true, like it currently is?
MessageHandler.getResponse() is a handler I wrote to check if I received a text message containing a specific (hardcoded) string of text from a specific phone number. It does block execution until it finishes checking, but the API I'm using has very aggressive rate limits. The API offers no callbacks -- it must manually be called.
It's not very clear what your whole code does. As commented by others, knowing what MessageHandler does would add some context.
The Thread.sleep static invocation will make the current thread sleep for at least the given amount of time,
subject to the precision and accuracy of system timers and schedulers
(see API)
If your MessageHandler.getResponse invocation blocks before returning, then you probably don't need to sleep at all.
However, if this task is repeated "endlessly", you probably want to use a ScheduledExecutorService instead, and run it based on a schedule.
Bottomline, Thread.sleep is not "bad practice" per se, but you seldom need to actually use it.
I fully agree with Mena's response, but to offer an alternate implementation to Thread.sleep, you can use a CountdownLatch to perform your looping:
public void blockingWaitForMessage(long sendTime, String phone) throws InterruptedException{
final CountDownLatch latch = new CountDownLatch(1);
while (!latch.await(5, TimeUnit.SECONDS)) {
if (MessageHandler.getResponse(sendTime, phone)) {
latch.countDown();
}
}
}
Using CountDownLatch.await handles both your boolean and temporal states!
You can use guava retrying library.
Retryer
It has nice API.
Or you can decorate ScheduledThreadPoolExecutor from Java library.
I am writing a blackberry app that communicates with a simple Bluetooth peripheral using text based AT commands - similar to a modem... I can only get it working on the blackberry using an event listener. So the communication is now asynchronous.
However, since it is a simple device and I need to control concurrent access, I would prefer to just have a blocking call.
I have the following code which tries to convert the communications to blocking by using a wait/notify. But when I run it, notifyResults never runs until getStringValue completes. i.e. it will always timeout no matter what the delay.
The btCon object runs on a separate thread already.
I'm sure I am missing something obvious with threading. Could someone kindly point it out?
Thanks
I should also add the the notifyAll blows up with an IllegalMonitorStateException.
I previously tried it with a simple boolean flag and a wait loop. But the same problem existed. notifyResult never runs until after getStringValue completes.
public class BTCommand implements ResultListener{
String cmd;
private BluetoothClient btCon;
private String result;
public BTCommand (String cmd){
this.cmd=cmd;
btCon = BluetoothClient.getInstance();
btCon.addListener(this);
System.out.println("[BTCL] BTCommand init");
}
public String getStringValue(){
result = "TIMEOUT";
btCon.sendCommand(cmd);
System.out.println("[BTCL] BTCommand getStringValue sent and waiting");
synchronized (result){
try {
result.wait(5000);
} catch (InterruptedException e) {
System.out.println("[BTCL] BTCommand getStringValue interrupted");
}
}//sync
System.out.println("[BTCL] BTCommand getStringValue result="+result);
return result;
}
public void notifyResults(String cmd) {
if(cmd.equalsIgnoreCase(this.cmd)){
synchronized(result){
result = btCon.getHash(cmd);
System.out.println("[BTCL] BTCommand resultReady: "+cmd+"="+result);
result.notifyAll();
}//sync
}
}
}
Since both notifyResults and getStringValue have synchronized clauses on the same object, assuming getStringValues gets to the synchronized section first notifyResults will block at the start of the synchronized clause until getStringValues exits the synchronized area. If I understand, this is the behaviour you're seeing.
Nicholas' advice is probably good, but you may not find any of those implementations in BlackBerry APIs you're using. You may want to have a look at the produce-consumer pattern.
It may be more appropriate to use a Latch, Semaphore, or a Barrier, as recommended by Brian Goetz book Java Concurrency in Practice.
These classes will make it easier to write blocking methods, and will likely help to prevent bugs, especially if you are unfamiliar with wait() and notifyAll(). (I am not suggesting that YOU are unfamiliar, it is just a note for others...)
The code will work ok. If you will use final object instead of string variable. I'm surprised that you don't get NPE or IMSE.
Create field:
private final Object resultLock = new Object();
Change all synchronized sections to use it instead of string field result.
I don't like magic number 5 sec. I hope you treat null result as timeout in your application.
The only model that I can come up with for running multiple similar processes (SIMD) using
Java Futures (java.util.concurrent.Future<T>) is as follows:
class Job extends Callable<T> {
public T call() {
// ...
}
}
List<Job> jobs = // ...
List<Future<T>> futures = ExecutorService.invokeAll(jobs);
for (Future<T> future : futures) {
T t = future.get();
// Do something with t ...
}
The problem with this model is that if job 0 takes a long time to complete, but jobs 1, 2, and 3 have already completed, the for loop will wait to get the return value from job 0.
Is there any model that allows me to get each Future result as it becomes available without just calling Future.isDone() and busy waiting (or calling Thread.sleep()) if none are ready yet?
You can try out the ExecutorCompletionService:
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html
You would simply submit your tasks and call take until you've received all Futures.
Consider using ListenableFuture from Guava. They let you basically add a continuation to execute when the future has completed.
Why don't you add what you want done to the job?
class Job extends Runnable {
public void run() {
// ...
T result = ....
// do something with the result.
}
}
That way it will process the result as soon as it is available, concurrently. ;)
A CompletionService can be polled for available results.
If all you want is the results as they become available however, we wrote an AsyncCompleter that abstracts away the detail of completion service usage. It lets you submit an Iterable<Callable<T>> of jobs and returns an Iterable<T> of results that blocks on next() and returns the results in completion order.