How to Catch Timed Out Exception - java

Code :
Class Manager {
Future fu = pool.invokeAll(workers, SEARCH_TIMEOUT, TimeUnit.SECONDS);
// calling the invoke call
search search= fu.get();
// callable
}
public class Search implements Callable<Search> {
Search call() {
// multiple workers will execute Code So don't want to catch timed out exception in here
// api value will be changing based on corresponding reference
api.search_api();
}
}
class api()
{
search_api(){
// How to catch a timed out exception in here
// catch(TimedoutException){} did not work in here
}
}
Is there a way that I can catch the TimedOut exception in the Class api under method search_api()?

You can catch TimeoutException like this code :
try {
Future fu = pool.invokeAll(workers, SEARCH_TIMEOUT,
TimeUnit.SECONDS);
// calling the invoke call
search search = fu.get();
} catch (TimeoutException e) {
e.printStackTrace();
}

You can also do it by the following way
try{
.
.
.
.
catch (RuntimeException e) {
// TODO: handle exception
}

Related

Could Java Future call its own get() function in its other members?

I wish to do this:
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
return 1;
});
f1.thenRun(() -> System.out.println(this.get()));
The last line doesn't compile. I just wish to do something inside thenRun function, and prints its own get() result inside it. I don't wish to use this return value outside calls to f1, to make code more tight.
Is there a way to do it?
Try CompletableFuture#thenAccept() where the argument is Consumer<Result>
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
return 1;
});
f1.thenAccept(System.out::println);
this refer to the caller instance(object) who call the instance method, you cannot use this inside a class and refer to the declared variable f1.
You can test if the task is done then print the result else print another message, giving it 3 seconds to be sure that it will be done for example :
f1.thenRun(() -> {
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
if (f1.isDone())
System.out.println(f1.get());
else
System.out.println("Not Done");
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});

How to shutdown an ExecutorService from one of its threads?

I want to stop the whole ExecutorService if one (specific thread) of the threads managed by it fails with an exception. Is it ok to simply call ExecutorService#shutdown from within the thread?
With Executorservice , if getting returned data from a thread ( using .get() method ) fails with an Exception , an ExecutionException will be thrown .
You have 2 case : passing Runnable to the submit method , or passing a Callable , in both of those cases you can use .get() method to retrieve data from the thread after execution.
So you can add .get() method to all the execution of threads and surround the calls of the submit method with a try catch block that handle ExecutionException .
This example will explain the idea :
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
static ExecutorService service = Executors.newFixedThreadPool(3);
public static void main(String[] args) {
try {
// Callable
System.out.println(service.submit(() -> {
return "Hello";
}).get());
} catch (ExecutionException e) {
System.out.println(e.getMessage());
// shutDown the service : if you delete the next line , service will still
// working
service.shutdownNow();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// Runnable
service.submit(() -> {
throw new IOException();
}).get();
} catch (ExecutionException e) {
System.out.println(e.getMessage());
// shutDown the service : if you delete the next line , service will still
// working
service.shutdownNow();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

How can i execute commands based on if the status of the previous one?

Basically i have 2 different commands i could possibly execute. If the first one does not work, I want to execute the second command.
Is there some easier, cleaner way to do this?
What would i even put in the if statement?
try
{
// code that may throw an exception
driver.findElement(By.id("component-unique-id-31")).click();
}
catch (Exception ex)
{
// Print to console
}
if(previous command threw an exception){
try
{
//Another command i want executed if the above fails
driver.findElement(By.xpath("//h3[normalize-space()='Something']")).click();
}
catch (Exception ex)
{
// handle
}
}
You can put the second command inside the catch block of the first try-catch, as following:
try
{
// code that may throw an exception
driver.findElement(By.id("component-unique-id-31")).click();
}
catch (Exception ex1)
{
try
{
//Another command i want executed if the above fails
driver.findElement(By.xpath("//h3[normalize-space()='Something']")).click();
}
catch (Exception ex2)
{
// handle
}
}
You can wrap up both the try-catch{} blocks within a single try-catch-finally{} block as follows:
try {
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.id("component-unique-id-31"))).click();
System.out.println("Within in try block.");
}
catch(TimeoutException e) {
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//h3[normalize-space()='Something']"))).click();
System.out.println("Within in catch block.");
} finally {
System.out.println("The 'try catch' is finished.");
}
PS: You must avoid catching the raw exception.

How to set timeout in a method in Java and retry method for a periodic amount of time

I java a java method, which makes a connection to a web service.
Sometimes this method takes too long to make the connection.
I want for example it it takes longer than 5 seconds, then to stop the current procedure and restart all over for 3 more times. If all times fail, then abort completely.
I have written the following until now:
private ConnectionInterface connectWithTimeout() throws MalformedURLException, Exception {
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException, MalformedURLException, Exception {
return connectWithNoTimeout(); //This is the method that takes to long. If this method takes more than 5 seconds, I want to cancel and retry for 3 more times. Then abort completely.
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
System.out.println( "Timeout Occured");
} catch (InterruptedException e) {
System.out.println( " "InterruptedException Occured");
} catch (ExecutionException e) {
System.out.println( ""ExecutionException Occured");
} finally {
future.cancel(true); // here the method gets canceled. How do I retry it?
}
System.out.println( "Connected !!");
return connectWithNoTimeout();
}
private ConnectionInterface connectWithNoTimeout() throws MalformedURLException, Exception {}
Your method already has a 5 seconds timeout. All you need to do now is to add some kind a loop with 3 repeats. You need a counter of timeouts and a break after successful attempt. Not sure what you want to do when other exceptions happen, added breaks there as well. Following code should do the job:
private ConnectionInterface connectWithTimeout() throws MalformedURLException, Exception {
int repeatCount = 0;
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException, MalformedURLException, Exception {
return connectWithNoTimeout(); //This is the method that takes to long. If this method takes more than 5 seconds, I want to cancel and retry for 3 more times. Then abort completely.
}
};
while (repeatCount < 3){
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
break;
} catch (TimeoutException ex) {
repeatCount++;
System.out.println( "Timeout Occured");
} catch (InterruptedException e) {
System.out.println( " "InterruptedException Occured");
break;
} catch (ExecutionException e) {
System.out.println( "ExecutionException Occured");
break;
} finally {
future.cancel(true); // here the method gets canceled. How do I retry it?
}
}
System.out.println( "Connected !!");
return connectWithNoTimeout();
}
First of all, I'd put the execution of that long command into a new thread so it will not block the Main Thread with the UI etc.
an approach:
Thread thr = new Thread() {
public void run() {
boolean error =false;
boolean success=false;
int time =0;
try {
while(tries<3&&!success){
//HERE GOES YOUR METHOD (connectWithNoTimeout(); ?)! Make sure to make the boolean "Success" = true if the connection is established
while (!error&&time<3) {
time++;
Thread.sleep(1000);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
};
It's mostly written by hand, you need to make changes, copy & paste will not work

How to wrap Thread with ReentrantLock into CompletableFuture call?

This is my current implementation which handles different file read/save operations consecutively:
public void runThread(MyThreadImpl myThreadImpl) {
synchronized (this) {
this.myThreadImpl = myThreadImpl;
notify();
}
}
synchronized public void run() {
while (true)
try {
wait();
Global.myReentrantLock.lock();
try {
try {
myThreadImpl.call();
} catch (FileException e) {
// trace e
} catch (RuntimeException e) {
// trace e
} catch (Exception e) {
// trace e
}
} finally {
Global.myReentrantLock.unlock();
}
} catch (InterruptedException e) {
// trace e
} catch (Exception e) {
// trace e
}
}
I have a problem that I don't wait for thread result before performing another operation, and I've come to a case where that is necessary.
Since I'm using Java 8, I wanted to wrap this in a CompletableFuture. How can I do this with my current implementation?
You could do the following:
Instead of storing the next job to be done as a single reference (this.myThreadImpl) that is updated once the lock is free, you could use a queue.
When a new job is added, a new CompletableFuture is created, and a reference to it is returned to the caller.
Once the job is completed, the future is completed.
Updating your code, and assuming queue is a blocking queue of type Queue<Pair<CompletableFuture<Void>, MyThreadImpl>>, you would have:
/**
* #return a Future that will complete once the passed MyThreadImpl has been run.
*/
public CompletableFuture<Void> runThread(MyThreadImpl myThreadImpl) {
Pair<CompletableFuture<Void>, MyThreadImpl> p =
new Pair<>(new CompletableFuture<>(),myThreadImpl);
queue.add(p);
return p.left;
}
public void run() {
while (true) {
try {
Pair<CompletableFuture<MyThreadImpl>, MyThreadImpl> p =
queue.take(); // will block until a job is added
try {
p.right.call();
p.left.complete(null); // Future<Void> can only be completed with null. Alternatively, it could be completed with a relevant result.
} catch (Exception e) {
p.left.completeExceptionally(e);
}
} catch (InterruptedException e) {
// trace e
}
}
}
Here, Pair just needs to be a pair-like pojo. (It could be apache commons's ImmutablePair, for example.)
Blocking queues are generally useful when stuff needs to be processed: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html
Also, have you looked at ExecutorService? You could use one that is based on a single thread to execute jobs in a serial way: it's submit(Callable<> task) method is quite like runThread() defined above, as it returns a Future<Void> that will tell you when the task is done.

Categories

Resources