I was looking for the ways to exit a method,
i found two methods
System.exit();
Return;
System.exit() - Exits the full program
Return exits current method and returns an error that remaining code are unreachable.
class myclass
{
public static void myfunc()
{
return;
System.out.println("Function ");
}
}
public class method_test
{
public static void main(String args[])
{
myclass mc= new myclass();
mc.myfunc();
System.out.println("Main");
}
}
There is no best way, it depends on situation.
Ideally, there is no need to exit at all, it will just return.
int a() {
return 2;
}
If there is a real need to exit, use return, there are no penalties for doing so.
void insertElementIntoStructure(Element e, Structure s) {
if (s.contains(e)) {
return; // redundant work;
}
insert(s, e); // insert the element
}
this is best avoided as much as possible as this is impossible to test for failure in voids
Avoid system.exit in functions, it is a major side effect that should be left to be used only in main.
void not_a_nice_function() {
if (errorDetected()) {
System.exit(-1);
}
print("hello, world!");
}
this pseudocode is evil because if you try to reuse this code, it will be hard to find what made it exit prematurely.
The best and proper way to exit from method is adding return statement.
System.exit() will shutdown your programm.
if you use system.exit once a thread goes there, it won't come back.
system.exit is part of Design of the Shutdown Hooks API
first of all your code will kill good programmers imagine this code Which is the Best way to exit a method this code example that how a return comes before a System.out.print(); as it becomes unreachable after the return statement lols
the command
System.exit(int status); (status=0 for Normal Exit && status=-1 for abnormal exit
is only used if you want to exactly quit your whole app whereas
the command
return;
is used to get out/return from a method
these two are different in their operations
Related
I'm currently creating a java programm where I want to run a method, after two conditions are fulfilled. So right when both conditions are occuring, the method should be called. The only way I can think of handling it is as I added it below, but it doesn't seem like the optimal way to do so.
Here no matter if method1 or method2 is called first, the following method is checking if the other condition is already fulfilledand then runs the method. Since there might be methods that depend on more conditions then two, are there more clearer way to handle it?
My example:
public class Test() {
private boolean condition1 = false;
private boolean condition2 = false;
public void method1(){
condition1 = true;
if(condition2){
run();
}
}
public void method2(){
condition2 = true;
if(condition1){
run();
}
}
public void run(){
//Is run when both conditions are true
}
}
Since there might be methods that depend on more conditions then two
As per the statement above I guess I can assume you might have more than two conditions, and perhaps multiple combinations? In that case you wouldn't want to verify the conditions in your run method.
You could have a dedicated method applying the required conditions as needed, something like this:
public void runIfTheConditionsAreMet() {
if(condition1 && condition2) {
run();
}
}
This way you would have a dedicated method to check for the conditions and call your run method only when necessary, without repeating code in your method1, method2, and you would have a place you could document the conditions (if necessary).
Your code would look a little bit cleaner, as below:
public void method1(){
condition1 = true;
runIfTheConditionsAreMet();
}
public void method2(){
condition2 = true;
runIfTheConditionsAreMet();
}
Ps. Even if you don't intend to have more conditions I think this solution would fit your needs.
If I were to open up this code, and have to understand it, I would have a much easier time if I saw something more like this:
public void run(){
if(condition1 && condition2){
// Now run the important code
}
}
Whatever calls were made to method1 and method2 before would be changed to calls to run(). This seems much more intuitive to me, instead of spreading the check out between two methods, either one of which may execute run().
Take a look at CountDownLatch.
I have a method that I would like to call. However, I'm looking for a clean, simple way to kill it or force it to return if it is taking too long to execute.
I'm using Java.
to illustrate:
logger.info("sequentially executing all batches...");
for (TestExecutor executor : builder.getExecutors()) {
logger.info("executing batch...");
executor.execute();
}
I figure the TestExecutor class should implement Callable and continue in that direction.
But all i want to be able to do is stop executor.execute() if it's taking too long.
Suggestions...?
EDIT
Many of the suggestions received assume that the method being executed that takes a long time contains some kind of loop and that a variable could periodically be checked.
However, this is not the case. So something that won't necessarily be clean and that will just stop the execution whereever it is is acceptable.
You should take a look at these classes :
FutureTask, Callable, Executors
Here is an example :
public class TimeoutExample {
public static Object myMethod() {
// does your thing and taking a long time to execute
return someResult;
}
public static void main(final String[] args) {
Callable<Object> callable = new Callable<Object>() {
public Object call() throws Exception {
return myMethod();
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Object> task = executorService.submit(callable);
try {
// ok, wait for 30 seconds max
Object result = task.get(30, TimeUnit.SECONDS);
System.out.println("Finished with result: " + result);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
System.out.println("timeout...");
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
Java's interruption mechanism is intended for this kind of scenario. If the method that you wish to abort is executing a loop, just have it check the thread's interrupted status on every iteration. If it's interrupted, throw an InterruptedException.
Then, when you want to abort, you just have to invoke interrupt on the appropriate thread.
Alternatively, you can use the approach Sun suggest as an alternative to the deprecated stop method. This doesn't involve throwing any exceptions, the method would just return normally.
I'm assuming the use of multiple threads in the following statements.
I've done some reading in this area and most authors say that it's a bad idea to kill another thread.
If the function that you want to kill can be designed to periodically check a variable or synchronization primitive, and then terminate cleanly if that variable or synchronization primitive is set, that would be pretty clean. Then some sort of monitor thread can sleep for a number of milliseconds and then set the variable or synchronization primitive.
Really, you can't... The only way to do it is to either use thread.stop, agree on a 'cooperative' method (e.g. occassionally check for Thread.isInterrupted or call a method which throws an InterruptedException, e.g. Thread.sleep()), or somehow invoke the method in another JVM entirely.
For certain kinds of tests, calling stop() is okay, but it will probably damage the state of your test suite, so you'll have to relaunch the JVM after each call to stop() if you want to avoid interaction effects.
For a good description of how to implement the cooperative approach, check out Sun's FAQ on the deprecated Thread methods.
For an example of this approach in real life, Eclipse RCP's Job API's 'IProgressMonitor' object allows some management service to signal sub-processes (via the 'cancel' method) that they should stop. Of course, that relies on the methods to actually check the isCancelled method regularly, which they often fail to do.
A hybrid approach might be to ask the thread nicely with interrupt, then insist a couple of seconds later with stop. Again, you shouldn't use stop in production code, but it might be fine in this case, esp. if you exit the JVM soon after.
To test this approach, I wrote a simple harness, which takes a runnable and tries to execute it. Feel free to comment/edit.
public void testStop(Runnable r) {
Thread t = new Thread(r);
t.start();
try {
t.join(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!t.isAlive()) {
System.err.println("Finished on time.");
return;
}
try {
t.interrupt();
t.join(2000);
if (!t.isAlive()) {
System.err.println("cooperative stop");
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.err.println("non-cooperative stop");
StackTraceElement[] trace = Thread.getAllStackTraces().get(t);
if (null != trace) {
Throwable temp = new Throwable();
temp.setStackTrace(trace);
temp.printStackTrace();
}
t.stop();
System.err.println("stopped non-cooperative thread");
}
To test it, I wrote two competing infinite loops, one cooperative, and one that never checks its thread's interrupted bit.
public void cooperative() {
try {
for (;;) {
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.err.println("cooperative() interrupted");
} finally {
System.err.println("cooperative() finally");
}
}
public void noncooperative() {
try {
for (;;) {
Thread.yield();
}
} finally {
System.err.println("noncooperative() finally");
}
}
Finally, I wrote the tests (JUnit 4) to exercise them:
#Test
public void testStopCooperative() {
testStop(new Runnable() {
#Override
public void run() {
cooperative();
}
});
}
#Test
public void testStopNoncooperative() {
testStop(new Runnable() {
#Override
public void run() {
noncooperative();
}
});
}
I had never used Thread.stop() before, so I was unaware of its operation. It works by throwing a ThreadDeath object from whereever the target thread is currently running. This extends Error. So, while it doesn't always work cleanly, it will usually leave simple programs with a fairly reasonable program state. For example, any finally blocks are called. If you wanted to be a real jerk, you could catch ThreadDeath (or Error), and keep running, anyway!
If nothing else, this really makes me wish more code followed the IProgressMonitor approach - adding another parameter to methods that might take a while, and encouraging the implementor of the method to occasionally poll the Monitor object to see if the user wants the system to give up. I'll try to follow this pattern in the future, especially methods that might be interactive. Of course, you don't necessarily know in advance which methods will be used this way, but that is what Profilers are for, I guess.
As for the 'start another JVM entirely' method, that will take more work. I don't know if anyone has written a delegating class loader, or if one is included in the JVM, but that would be required for this approach.
Nobody answered it directly, so here's the closest thing i can give you in a short amount of psuedo code:
wrap the method in a runnable/callable. The method itself is going to have to check for interrupted status if you want it to stop (for example, if this method is a loop, inside the loop check for Thread.currentThread().isInterrupted and if so, stop the loop (don't check on every iteration though, or you'll just slow stuff down.
in the wrapping method, use thread.join(timeout) to wait the time you want to let the method run. or, inside a loop there, call join repeatedly with a smaller timeout if you need to do other things while waiting. if the method doesn't finish, after joining, use the above recommendations for aborting fast/clean.
so code wise, old code:
void myMethod()
{
methodTakingAllTheTime();
}
new code:
void myMethod()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
methodTakingAllTheTime(); // modify the internals of this method to check for interruption
}
});
t.join(5000); // 5 seconds
t.interrupt();
}
but again, for this to work well, you'll still have to modify methodTakingAllTheTime or that thread will just continue to run after you've called interrupt.
The correct answer is, I believe, to create a Runnable to execute the sub-program, and run this in a separate Thread. THe Runnable may be a FutureTask, which you can run with a timeout ("get" method). If it times out, you'll get a TimeoutException, in which I suggest you
call thread.interrupt() to attempt to end it in a semi-cooperative manner (many library calls seem to be sensitive to this, so it will probably work)
wait a little (Thread.sleep(300))
and then, if the thread is still active (thread.isActive()), call thread.stop(). This is a deprecated method, but apparently the only game in town short of running a separate process with all that this entails.
In my application, where I run untrusted, uncooperative code written by my beginner students, I do the above, ensuring that the killed thread never has (write) access to any objects that survive its death. This includes the object that houses the called method, which is discarded if a timeout occurs. (I tell my students to avoid timeouts, because their agent will be disqualified.) I am unsure about memory leaks...
I distinguish between long runtimes (method terminates) and hard timeouts - the hard timeouts are longer and meant to catch the case when code does not terminate at all, as opposed to being slow.
From my research, Java does not seem to have a non-deprecated provision for running non-cooperative code, which, in a way, is a gaping hole in the security model. Either I can run foreign code and control the permissions it has (SecurityManager), or I cannot run foreign code, because it might end up taking up a whole CPU with no non-deprecated means to stop it.
double x = 2.0;
while(true) {x = x*x}; // do not terminate
System.out.print(x); // prevent optimization
I can think of a not so great way to do this. If you can detect when it is taking too much time, you can have the method check for a boolean in every step. Have the program change the value of the boolean tooMuchTime to true if it is taking too much time (I can't help with this). Then use something like this:
Method(){
//task1
if (tooMuchTime == true) return;
//task2
if (tooMuchTime == true) return;
//task3
if (tooMuchTime == true) return;
//task4
if (tooMuchTime == true) return;
//task5
if (tooMuchTime == true) return;
//final task
}
Well, I was wondering how java handles code reading and running, for example if I wrote:
static void doSomething(){
doSomethingElse();
doYetAnotherThing();
}
Will it wait for doSomethingElse() to complete before it runs doYetAnotherThing()? Or will it just run both?
I guess if it sets a variable, variable = setAVariable(); it will retrieve the variable before continuing, but if the method contains an infinite loop it would get stuck.
Java will run your code sequentially unless u tell it otherwise (by creating threads.)
If you jave an infinite loop in function doSomthingElse() then doYetAnotherThing() will never execute and doSomething will never terminate.
public static void main(String[] args)
{
doSomethingElse();
doYetAnotherThing();
}
private static void doYetAnotherThing() {
System.out.println("Hi Agn");
}
private static void doSomethingElse() {
System.out.println("Hi");
while(true) // Infinite Loop
{
}
}
This will print to output:
Hi
But not: Hi Agn.
For making both functions run you need to remove the infinite loop in doSomethingElse().
UPDATE:
However if you cant do that and still want to run the code above, you can use threads:
Main Class:
public class javaworking
{
static MyThread t1, t2;
Thread tc;
public static void main(String[] args)
{
t1 = new MyThread(1);
Thread tc = new Thread(t1);
tc.start();
t2 = new MyThread(2);
tc = new Thread(t2);
tc.start();
}
}
Thread class that contains all your functions:
public class MyThread implements Runnable {
int ch;
public MyThread(int choice)
{
ch = choice;
}
#Override
public void run() {
// TODO Auto-generated method stub
switch(ch)
{
case 1:
doSomethingElse();
break;
case 2:
doYetAnotherThing();
break;
default:
System.out.println("Illegal Choice");
break;
}
}
private static void doYetAnotherThing() {
// TODO Auto-generated method stub
System.out.println("Hi Agn");
}
private static void doSomethingElse() {
// TODO Auto-generated method stub
System.out.println("Hi");
int i = 1;
while(true)
{
System.out.println(i++);
}
}
}
Please note: The code I provided is merely an example. I didn't do any error handling or follow the recommended standards. The code works and that's it.
Logically the program will read top to bottom. And as a programmer that's all you really need to know. However, behind the scenes this may not necessarily be the case. But you're guaranteed the results as if they ran sequentially.
Sometimes your processor will run lines of code that should never even have been executed! This is because of something called branch prediction(which has a nice explanation on this answer, though not java the idea is demonstrated at a lower level).
Again, you can work under the assumption that everything in the same Thread, will execute in written order.
These are synchronous calls executing in one thread so they are executed one after the other, ie. first doSomethingElse(); then doYetAnotherThing();. If you wanted them to be executed concurrently you could put each in different threads, then the order would not be guaranteed.
One listing from the spec is here:
http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html
The gist is that one function must return before the next one is called. I can't say what that means in your case without knowing what your functions are doing. They could return because they finished or because they forked/spawned off another process/thread/async action. There are more subtleties to this but I'm not getting into anything further than this since they over complicate and obfuscate the answer.
Based on the terminology you use, I would suggest starting with a tutorial. Java doesn't read your code. Java is a language. The compiler will 'read' and parse your code, and generate bytecode that will be executed by the JVM.
And yes, if you cause an infinite loop it's a problem and your program won't exit.
I'm having a programming issue related to bad recursion and StackOverflowError.
I've got this case in a separate thread:
public void subscribe(final String channel) {
try {
// blocking command
client.subscribe(channel);
} catch(ConnectionException e) {
subscribe(channel);
}
}
Say this ConnectionException is only happening periodically (something like every minute). After a few hundreds, I obviously obtain a StackOverflowError.
I know what's happening but I have no idea how I could solve this (i.e re-subscribing silently without increasing the calling stack). Any ideas?
Why not using a simple loop like his?
public void subscribe(final String channel) {
while(true){
try {
// blocking command
client.subscribe(channel);
return;
} catch(ConnectionException e) {
// ignored
}
}
}
Right now you have an infite recursion.
Put a recursion breaking condition. You need to have a condition where recursion should stop. Put an if block and stop the recursion logically at some point.
Though I know it'll be a bit silly to ask, still I want to inquire more about the technical perspective of it.
A simple example of an infinite loop:
public class LoopInfinite {
public static void main(String[] args) {
for (;;) {
System.out.println("Stack Overflow");
}
}
}
How can I interrupt (stop) this infinite loop from outside of this class (e.g., with the help of inheritance)?
I feel dirty even writing this, but...
From a different thread, you could call System.setOut() with a PrintStream implementation, which throws a RuntimeException when you call println().
We can achieve it using volatile variable, which we will change ouside Thread and stop the loop.
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
This is better way to write Infinite Loop.
public class LoopInfinite{
private static volatile boolean cancelled=false;
public static void main(String[] args){
for(;!cancelled;) { //or while(!cancelled)
System.out.println("Stackoverflow");
}
}
public void cancel(){
cancelled=true;
}
}
You can get at the thread running the infinite loop from a different thread and call interrupt on it. You'll have to be very sure what you are doing though, and hope that the interrupted thread will behave properly when interrupted.
Here, I've named the thread with the offending loop for easier identification. Beware that the following solution is vulnerable to race conditions.
Thread loop = new Thread() {
public void run() {
Thread.currentThread().setName("loop");
while(true) {
System.out.print(".");
}
}
}.start();
Then in some other class:
ThreadGroup group = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
for(Thread t : threads) {
if(t.getName().equals("loop")) {
/* Thread.stop() is a horrible thing to use.
Use Thread.interrupt() instead if you have
any control over the running thread */
t.stop();
}
}
Note that in my example I assume the two threads are in the same ThreadGroup. There is no guarantee that this will be the case, so you might need to traverse more groups.
If you have some control over this, a decent pattern here would be to have while(!isInterrupted()) instead in the loop declaration and use t.interrupt() instead of t.stop().
My only advice to you, even after posting this, is to not do this. You can do it, but you really shouldn't.
I think this is not possible. Only using break within the loop. You could use
while(cond) {}
And from some other place make it false
You can interrupt this thread by keeping its static reference of inherited reference to this Thread [main] by asking from Thread.currentThread(), like this
public class LoopInfinite{
public static Thread main = null;
public static void main(String[] args){
main = Thread.currentThread();
for(;;)
System.out.println("Stackoverflow");
}
}
And to terminate you can call this from some other thread
LoopInfinite.main.interrupt();
But it will only work if both threads are part of the same group. Otherwise calling thread will get SecurityException
You cannot stop this from outside of this class. If you use inheritance you can overwrite your loop, but without abort-flag you won't be able to do so.
Very open question, but stopping such loop would most likely require you to operate from another thread. The other thread would then need to set some variable that your infinite loop can check regularly, and if the variable has a certain value; break out of the loop.
You won't be able to interrupt this particular loop without halting the process entirely. In general, if you're trying to do it from an external source (I'm assuming you have no control over the source code, because if you did you could easily set a condition in the loop, such as a boolean you could set from an external Thread), you will have to halt the running Thread, whether you do this through the Thread object (you'll have to find a reference to it somehow, for example by looping through existing Threads), or whether you halt it as a system process.
Another option would be to override the method with a loop that isn't an infinite loop, but unfortunately that doesn't apply to your example because it's a static method.
Your kind of problem looks like a Threading problem. But still, it is now a a good practice to include a stopping flag even in threads
If you need an "infinite" loop, you sure need a thread (else your app will be stuck until the end of the loop).
class BigLoop extends Thread
{
private boolean _sexyAndAlive = true;
// make some constructor !
public void softTerminate()
{
_sexyAndAlive = false;
}
public void run()
{
try
{
while( _sexyAndAlive )
{
// Put your code here
}
}
catch( Some Exceptions ... )
{
// ...
}
// put some ending code here if needed
}
}
// in another file :
BigLoop worker = new BigLoop();
worker.start(); // starts the thread
// when you want to stop it softly
worker.softTerminate();
So, this is a simple method to have background running loop.
Add a variable shouldBreak or something which can be set using getter and setter.
public class LoopInfinite {
private boolean shouldBreak = false;
public boolean isShouldBreak() {
return shouldBreak;
}
public void setShouldBreak(boolean shouldBreak) {
this.shouldBreak = shouldBreak;
}
public static void main(String[] args) {
// Below code is just to simulate how it can be done from out side of
// the class
LoopInfinite infinite = new LoopInfinite();
infinite.setShouldBreak(true);
for (;;) {
System.out.println("Stackoverflow");
if (infinite.shouldBreak)
break;
}
}
}
Here is what I did:
while(Exit == false){
Scanner input = new Scanner(System.in);
String in = input.next();
switch(in){
case "FindH":
FindHyp hyp = new FindHyp();
float output = hyp.findhyp();
System.out.println(output);
case "Exit":
Exit = true;
break;
}
}