In the following scenario,
public void fooMethod()
{
try
{
methodToCall();
}catch( FooException exception )
{
methodToCall();
}
}
private int methodToCall() throws FooException
{
throw new FooException();
}
I want to callmethodToCall (for example) 10 times to try if it succeeds.
Because of the fact that in the catch block, no exception is caught and with the above given example, the methodToCall is called two times in total (one in the try block and one in the catch block.)
How should I design the code so that methodToCall will be called 10 times even if it throws the given exception.
Edit
The actual fooMethod is much more complicated than this and I cannot call it recursively because several other jobs are done than before this try-catch clause.
The for loop will ensure 10 calls are made. And the try catch will prevent exiting from the loop.
public void run10TimesWhatsoever() {
for(int i = 0; i < 10; ++i) {
try {
methodToCall();
} catch (final FooException ignore) {
}
}
}
However, if you want to call at MOST 10 times and stop when it succeed you may use something like that
public void attemptUpTo10Times() {
for(int i = 0; i < 10; ++i) {
try {
methodToCall();
break; // exit the loop if no exception were thrown
} catch (final FooException ignore) {
if (i == 9) {
throw new IllegalStateException("Failed 10 times in a row");
}
}
}
}
public void fooMethod()
{
int counter = 0 ;
while(counter < 10){
try
{
methodToCall();
counter = 11;
}catch( FooException exception )
{
counter++;
}
}
}
Related
I have a method, that writes about 7 million entries to the queues.I'm reading the entries one by one, in multiple threads, and writing it to a DB. Here is the code snippet for the class that does it.
Again, this is executing in a multithreading environment.
private class WriteRunner<T> implements Callable<Long> {
// member variables
public WriteRunner(ConcurrentLinkedQueue<T> elementsQueue,...)
//constructor
}
#Override
public Long call() throws Exception {
while (!elementsQueue.isEmpty()) {
int failures = 0;
T t = elementsQueue.poll();
while (true) {
try {
// write to DB
break;
} catch (Exception e) {
//Log error
//Wait for 10 seconds and retry
Thread.sleep(10000);
if (++failures > 10) {
throw new Exception(
String.format("[TID: %d] Connection repeatedly failed.", threadId));
}
}
}
}
//log more stuff
return (long)total;
}
}
Here is how I'm calling the method
for (int i = 0; i < N_THREADS; i++) {
completionService.submit(
new WriteRunner<T>(elementsQueue ,...));
}
long total = 0;
for (int i = 0; i < N_THREADS; i++) {
total += completionService.take().get();
}
I'm missing as many entries, as there is the number of exceptions.
My idea is to, retry on the same 't' element that's the latest poll.
What is going wrong with the exceptions?
i'm trying to build a program for multiplying two matrices (A[a,b], B[c,d]) using a*d threads (that will be used to print the sum of one index in the finished matrix), for this purpose, i'm using a 'monitor' class that will be used as a controller to synchrosize between the threads, 'multiplier' class to represent the single thread and a main program class. My idea is that the threads will have their calculations, and when thread(0,0) will print his sum, he will signal the next in line. For some reason after printing the first index - all the threads stay in waiting mode and won't test my condition. Could you look at my code and tell me where is my mistake?
Monitor class:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
final class Monitor {
private Lock lock;
int index;
Condition cond;
public Monitor () {
lock = new ReentrantLock();
cond = lock.newCondition();
this.index = 0;
}
public synchronized void finished(int x, double sum) throws InterruptedException {
lock.lock();
if(index != x) {
while(index != x) cond.await();
System.out.printf("%9.2f ",sum);
index++;
lock.unlock();
cond.signalAll();
}
else {
System.out.printf("%9.2f ",sum);
index++;
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
}
if(index % 5 == 0) System.out.println();
}
}
Multiplier:
public class Multiplier extends Thread {
private int index;
private double [] vectorOne;
private double [] vectorTwo;
private Monitor monitor;
private double sum;
//constructor
public Multiplier(int index, Monitor monitor,double [] vectorOne,double [] vectorTwo) {
this.index = index;
this.monitor = monitor;
this.vectorOne = vectorOne;
this.vectorTwo = vectorTwo;
}
public void VecMulti() {
sum = 0;
for (int i = 0 ; i < vectorOne.length ; i++)
sum += vectorOne[i] * vectorTwo[i];
}
public double getSum() {
return sum;
}
public void run() {
VecMulti();
try {
monitor.finished(index, sum);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Main class:
public class MatrixMultiTest {
public static void main(String[] args) {
Monitor monitor = new Monitor(3*5);
Matrix A = Matrix.random(3,4);
Matrix B = Matrix.random(4,5);
System.out.println("Matrix No1");
A.show();
System.out.println();
System.out.println("Matrix No2");
B.show();
System.out.println();
System.out.println("Multi Matrix");
for (int i = 0; i < 3; i++)
for (int j = 0; j < 5; j++) {
Multiplier myThr = new Multiplier(i*5+j,
monitor,A.getRow(i),B.getCol(j));
myThr.start();
try {
myThr.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
The finished() method is riddled with problems:
The first problem is the synchronized keyword. It must be removed. With this keyword, if the first entering thread has a non-zero index, the program will deadlock - the thread will forever be parked waiting for the condition to signal, which will never come, because no other thread can enter the finished() method.
The second fault lies with the else block:
else {
System.out.printf("%9.2f ",sum);
index++;
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
try { lock.unlock(); }
catch (java.lang.IllegalMonitorStateException e) {};
}
It never invokes cond.signalAll(), so after the thread with index=0 gets through, others will stay parked forever.
The third problem is that in if(index != x) {.. block, cond.signalAll() and lock.unlock() come in wrong order:
lock.unlock();
cond.signalAll();
Condition's signalAll() method documentation states:
An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called. Implementations must document this precondition and any actions taken if the lock is not held. Typically, an exception such as IllegalMonitorStateException will be thrown.
These two lines of code must be switched in order, or an IllegalMonitorStateException will be thrown.
A working version of the method can look something like this:
public void finished(int x, double sum) throws InterruptedException {
try {
lock.lock();
while (index != x) {
cond.await();
}
System.out.printf("%9.2f ", sum);
index++;
cond.signalAll();
} finally {
lock.unlock();
}
if (index % 5 == 0) System.out.println();
}
Funny enough, the code provided by OP actually works even with all these faults, but only due to this block of code in the MatrixMultiTest class:
try {
myThr.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Every thread is created and then started and joined sequentially, thus only one thread ever tries to acquire the implicit lock on the synchronized finished() method at any moment in time, and i*5+j index value ensures that the threads acquire this implicit lock in order of their index: 0, 1, 2 etc. It means that inside the method, index is always equal to x, and every thread goes through else block in finished(), allowing the program to complete execution. cond.await() is actually never invoked.
If the join block is removed, then some values might get printed, but the program will eventually deadlock.
I am new to Java. I am trying to create a Java Program that has the ability to retry itself when an exception occur in the program (which work fine). Now the problem I have now is in the for loop. In this code, when something went wrong in the for loop, the program itself will jump out of that loop and go to the catch method. After that if the retry is less than MAX_RETRIES, then the program will relaunch from the beginning. This is what I am struggling with. What I want is let say if there is an exception occur in the for loop when printing let say 5, I want the program to retry where the exception in the for loop occur not relaunch from the beginning. Are there ways to do it? I am struggling with this for a while and cannot seems to find a way to do it. Help and code for reference will be appreciated. This is the best way I can think of to simplify my code. In my real application, the for loop I have right now is to Iterate though a list of record from the database.
main.java
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
try {
while (retry <= MAX_RETRIES) {
//method1
//stuff code
//more code
//method2
for (int i = 0; i < 11; i++) {
System.out.println("i");
}
}
System.out.println("-----Finish Process-----");
break;
} catch (Exception e) {
e.printlnStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
I think it solve your problem
public class main {
private static int retryCounter = 1;
private static int MAX_RETRIES = 3;
public static void main(String[] args) {
int retry = 1;
while (retry <= MAX_RETRIES) {
try {
//method1
//stuff code
//more code
//method2
int i=0;
while (i < 11) {
try {
System.out.println(i);
i++;
} catch (Exception e) {
e.printStackTrace();
i++;
if (i == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
retry++;
} catch (Exception e) {
e.printStackTrace();
retry++;
if (retry == MAX_RETRIES) {
System.out.println("Program retried" + retry);
System.out.println("Program Terminated");
}
}
}
System.out.println("-----Finish Process-----");
}
}
I have an idea that might help. I can't show any example code, but it might be possible to set up a flag/signal1 after you complete each step in executing the program. Then, when the program retries, it can automatically skip to that point in code where it last stopped.
1: I don't know what it's called in java
This is my first time using exception handling so be gentle. I have a simple blob class that accepts an ID, the id must be between 30 and 50 or else an exception is thrown.
public class Blob {
int id;
public Blob() {
}
public Blob(int id) throws Exception {
this.id = id;
if (id < 30 || id > 50)
throw new Exception ("id = " +id+ ", must be between 30 and 50 inclusive");
}
}
It should prompt the user to enter an id, and throw the exception if it's not between 30 and 50, and should continue until the user enters a valid input and then simply displays the id number.
public class BlobCreator {
public static void main(String[] args) {
int id;
Scanner scan = new Scanner(System.in);
System.out.println("Enter ID number: ");
id = scan.nextInt();
do {
try {
Blob b = new Blob(id);
}
catch (Exception e) {
System.out.println(e);
}
System.out.println("Enter a different ID: ");
id = scan.nextInt();
}
while(true);
}
System.out.println("Blob ID: " +id);
}
I think that I am using the throw and catch correctly, but my loop isn't working correctly so I think that should be a simple fix but I can't get it just right. Also is using a while loop like I have the best way for this situation or is there a better way to loop through throw and catch?
Thanks for any and all help
You should place the break; after the code is executed successfully.
do {
try {
Blob b = new Blob(id);
break;
}
catch (Exception e) {
System.out.println(e);
}
System.out.println("Enter a different ID: ");
id = scan.nextInt();
} while(true);
So each time the loop would reach the end of its body, it would break out of the loop. You only should break after the blob is created successfully. Although I dont see why you put a break anyway. The while loop can check if the entered input was valid and simply stop the loop.
I modified the while in a do-while loop... By using true the loop will run forever, unless no exception is thrown by the constructor... This makes the code more generic (if you modify the conditions of the blob-construction, you don't have to modify the condition of the while loop).
Sorry, its kind of late to the party. Hope users who endup here may find this useful.
The use of break keyword is discouraged
Here is a very simple implementation to break away after implementing a retry mechanism
This iterates over the loop for the specified number of times and also if the exception still persists, then the exception is thrown. This can be leveraged for an actual real world scenario where the resttemplate might actually result in IO/Network errors and can be retried in those cases
public class TestClass {
public static void main(String[] args) throws Exception {
try {
int c = anotherM();
System.out.println("Now the value is" + c);
} catch (Exception e) {
System.out.println("Inside" + e);
}
}
public static int anotherM() throws Exception {
int i = 4;
Exception ex = null;
while (i > 0) {
try {
System.out.println("print i" + i);
throw new IOException();
// return i;
} catch (Exception e) {
System.out.println(e);
i--;
if (i == 1) {
ex = new Exception("ttt");
}
}
}
if (ex != null) {
throw new Exception("all new");
} else {
return i;
}
}
}
I hava a method called test() that throws an exception.
I want to write a loop that executes as long as it throws an exception, and breaks when it no longer throws an exception.
Can any one hint me on the logic that must be use?
For example I tried,
int i=0;
while(test())
{
i++;
}
System.out.println(i);
int i=0;
while (true) {
try {
test();
break;
} catch (Exception e) {
i++; // Loop will continue
}
}