How to avoid stack overflow error - java

I have a program which can be defined as something like this
reset() {
//sets all variables to initial values
//clears all arrays
method1();
}
method1 (){
//doSomeStuff;
method2();
}
method2(){
//doStuff
method3();
}
method3(){
//doStuff
if (jobDone) reset(); //here the cycle closes
else method2();
}
All these methods are quite calculations heavy.
Depending on the input data and the result the program may do just a couple of cycles and throw a 'stack overflow' error.
I have changed the VM flag -Xss (-Xss8M) but this doesn't really solve the problem.
Is there any way to make it working almost infinitely?

Solution previously mentioned by Luiggi Mendoza: How to avoid stack overflow error
When you call reset, it calls method1, it calls method2, it calls method3 and it calls either reset or method2 both causing infinite cycle in recursion.
You probably want:
if (jobDone) return; // here the cycle realy closes
instead of
if (jobDone) reset(); //here the do _not_ close
In case you realy want infinite cycling of your code this will not cause SO due to method calling of reset or methodi:
// assuming jobDone is actually a method, you might need this variable
boolean startReset = true;
while (true) {
if (startReset) {
//sets all variables to initial values
//clears all arrays
//doSomeStuff from method1;
}
//doStuff from method2
//doStuff
startReset = jobDone;
}
}

Related

How to stop execution of a method but continue the parent loop?

If the code faced a specific case I want to stop the current execution but continue the parent loop.
main() {
while(line not empty) {
// blablabla
method1()
// tadatadatada
}
}
method1() {
// blablabla
method2()
// etcetcetc
}
method2() {
// blablabla
if (var == 1)
stop the execution of the current method and parent method
// etcetcetc
}
In the case explained below, if var == 1, all etcetcetc part of code must not be executed, but tadatadatada must be...
So I want to stop all children executions.
Is there a solution to do that in Java?
Return a value from method2 and check it in method1. If it meets a condition, return from method1 too.
Something like:
method1() {
var shouldBreak = method2();
if (shouldBreak) {
return
}
// more stuff
}
Look into Java Multithreading. This will allow you to run multiple methods simultaneously and give you full control over when to stop a specific thread.
Here's a starting point from another: Threads in Java
I don't quite understand fully what you're asking as your example doesn't have extensive clarity, but hopefully this is what you're looking for.

end of the program java based on condition

I have a requirement where i need to call multiple methods in a sequential manner. But if any one of the method fails due to a validation, the program should not continue. I cannot use "Throw Exception because these are not actually exception rather than a condition that satisfies my requirement and after satisfying it, I don't want the program to continue.
Below is a piece of code for example and understanding. Even i use Return, it still continues to next method.
public void method1(){
System.out.println("Method 1");
return;
}
public void method2(){
System.out.println("Method 2");
return;
}
public void method3(int a) throws Exception{
System.out.println("Method 3");
if (a==3) FinalMethod();
return;
}
public void method4(){
System.out.println("Method 4");
return;
}
public void method5(){
System.out.println("Method 5");
return;
}
public void FinalMethod() {
System.out.println("This is the final method - end of the program");
return;
}
public void callMethod() throws Exception{
method1();
method2();
method3(3);
method4();
method5();
}
The method callMethod will be called from Main method. Please help me to learn this.
Edited: If The argument is 3 in method3, it should call Finalmethod and after that the program should end. I dont want it to go for method4 and method5.
Why not have the methods return a boolean to determine if the next method should run?
This is what's currently going on in in the stack when you call FinalMethod from method3:
main -> callMethod -> method3 -> FinalMethod
So when FinalMethod finishes, you go back to method3, and from there, go back to callMethod, and continue running to the end.
What I would do is make method3 return a boolean if you want to exit and call it with regard to this:
public boolean method3(int a) {
System.out.println("Method e");
return a==3;
}
...
//In callMethod
if (method3(3)) { //If we want to exit after running method3
FinalMethod();
return;
}
Though you may use System.exit(exitCode), this is not good practice, as it violates the program flow - that the program will only end at the end of the main function.
Though method3 is currently throwing an exception, you don't actually throw one in the method. However, exceptions should only be used for undefined behaviour (particularly relating to circumstances beyond your control, eg. external code). It is preferable to provide a user-friendly error and continue the program if possible, or exit gracefully if not.
Unrelated tips:
You do not have to call return at the end of a void function.
By default, you should make methods private, and only make them public when required
Calling return at the end of a method block is redundant in this scenario.
Assuming that you are looking to terminate the program on error, you can possibly use System.exit(-1) in your catch (if you follow this way), or in the if statement, if this is how you are checking for the error
Edit: I should also clarify that there is no specific meaning to using System.exit(-1) as opposed to using any System.exit(n) where n != 0, unless otherwise specified in your own documentation

Turn the main into a thread

I created a program that runs in a sort of loop, and it stops only if a particular event happens; i forgot to implement the possibility to interrupt the program from "outside", for example typing "halt" in the prompt.
So now i have something like this:
public void main(....) {
instruction1;
instruction2;
while(true) {
if(???)
break;
}
}
And want change it in something like:
main() {
do {
instruction1;
instruction2;
...
...
} while(prompt do not contains 'halt');
I don't think that you want to turn main into a thread, try something like
while(true){
if(inputScanner.hasNext() && inputScanner.next().equals("halt")){
break;
}
/* Do whatever is needed */
}
What happens is that the scanner is checked for input without blocking the loop with the hasNext() method, and then only when it does have data to read in does it read the data in.

Explanation on Thread

I have the following Java program:
public class A extends Thread {
int count;
#Override
public void run() {
while (true)
count++;
}
public static void main(String...strings){
A obj = new A();
obj.start();
System.out.println("The value of count is " + obj.count);
}
}
When running this program the output is: The value of count is 0 (and the program stays running). As far as my understanding with thread it should run in an infinite loop and never print 0. Could anyone help me understanding the nature of this program.
The thread starts at about the same time as the System.out.println runs, and since the thread is background, the println does not wait for it to run, and so you are seeing the initial value of count.
Also as an aside, the count variable should be declared volatile to ensure that the main thread sees changes to the variable made in the loop thread.
The "thread" isn't doing the print, your main is. What were you expecting to happen?
You should also use some kind of protection so both threads can safely access the variable.
Wouldn't the System.out call only run once?
I would put the System.out.println call inside the while loop.
Its probably better to use a getter/setter method for count and make sure only one or the other can access the variable at any given time.

Stop current running thread with certain condition, with finally block being called

I have a method which is long and has many inner loops, at some point in the inner loop if a certain condition is met, I want the thread to be terminated but I also want the finally block to be called so clean up also happens. How can I do this?
Call return; when you want to stop. That will leave the loop and run the finally (so long as the loop with the return statement is within the try block).
E.g.
pseudocode:
public void run () {
try {
loop {
loop {
if (condition) return;
}
}
} finally {
// always run
}
}
Remember that "terminating the thread" really just means-- or should mean!-- that the run() method exits. Put the finally outside the loop, as the last thing in the thread's/Runnable's run() method.

Categories