In a highly concurrent program with lots of shutdown operations, wondering how to set the exit code without prematurely calling System.exit()? Possible to set an "execute this code when everything else is done" method? but I'd really just like to prematurely set the exit code.
If I understand correctly what you want is to somehow keep the exit code, run some methods and then call System.exit with the pre-decided exit code.
IMO what you should do is use Shutdown hooks instead. I.e. your code will run before the JVM shuts down and (if I got your requirement correctly) will have the same result with a straightforward coding implementation (i.e. instead of using using state variable and unusual coding logic to achieve what you are trying to do etc)
Have a master thread spawn off all other threads such that it only shuts down when all other threads are complete.
In a highly concurrent program with lots of shutdown operations
This is a code smell to me.
I can understand how multiple threads might want to shut down, but they shouldn't be allowed to do so.
Instead, I would create a global method called initiateShutdown(int code). This method would contain logic to determine when it's appropriate to actually shut down. Since you may not want a thread returning from this method, you could implement some sort of never-returning lock, and consign the thread to waiting on this lock.
Just store the result somewhere and use any suitable synchronization tool to tell that you are done. When you are done, just read the stored result and exit using System.exit(result).
I'm curious, if several threads set the result, which should you use?
Related
I was wondering if there is some way in Java to stop thread immediately. I don't want to check its interrupted status, I need to stop it immediately. That's because in thread's run method there are many calculations and to achieve what I want using interrupted I would have to inject status check everywhere. So is there some way to interrupt thread immediately? Maybe stop() method? I know it's is said it shouldn't be used because of deadlocks but if it could solve my problem (even if it would cause another ;) ) I could use it. So? P.S. I know there were other, similar questions but everywhere people give similar questions to interrupted() which doesn't suit me.
The question/answer that #Alya'aGamal points to is the right one.
If your app's design assumes that forcibly stopping a thread, or a process, or a program (like using kill -9 or stopping it via the Task Manager on Windows) is an okay thing to do, then you really need to justify that, because it sounds like a bad design choice. If you used someone else's app and the only way to close it on demand was to forcibly stop it, wouldn't you think that was a rather major flaw?
If you have long-running loops or algorithms and it's important to be able to stop them at an arbitrary point then you MUST put some kind of regular status or signal check in place in order to do this properly.
Always design your apps in a way such that there is a nice, friendly, graceful way for them to exit from all situations other than things outside your control (e.g. another app starts saturating the CPU, a hard disk dies, a RAM chip gets fried, a meteor hits the Earth, etc.)
As others have said, it's not a good idea to just kill a thread, which is why the stop() method has been deprecated. It's just too easy to introduce deadlocks this way. There are other reasons why stopping a thread externally is bad, but I won't get into them here.
Status checks really are the only other way to go, but I can understand why you'd want to avoid them. Checks add overhead and make the code cumbersome if your run() method has many lines of code... but there's simply no other thread-safe way to stop a thread.
That said - there are four components of deadlock: mutual exclusion, hold and wait, non-pre-emption, and circular wait. If you can guarantee that any one of these conditions will never be met inside your run() method, then you will never encounter a deadlock by calling stop().
We are unfortunately stuck for the medium term with having to call a method that can sometimes never return, and forever freeze the thread that called it. Fortunately that actual call interacts with little else in the system, and returns no value. So we're thinking that until we can fix the offending code, we need to run the invocation in a separate thread that we can monitor and interrupt if it exceeds a timeout.
Clearly smarter people than I have already solved this problem and left their gifts in the concurrent package, and since this will be my first use of anything in the concurrent package, I'd just like to confirm that I'm picking the best approach.
So I'm thinking I'd get an ExecutorService by calling Excutors.newSingleThreadExecutor, submit a Runnable to it, and then call the overload of Future.get() that accepts a timeout as a parameter.
The actual task to perform is just to call a single void method on an object that I can pass into the constructor of the Runnable.
If this is the right approach, or close, I'd also really appreciate a short code sample if you're feeling generous with your time. :)
Thanks
Clearly smarter people than I have already solved this problem
Actually its not really solved IMHO.
To interrupt a task it has to be well behaved and check the interrupt or it won't actually stop. However, if its well behaved its unlikely to need to be killed in the first place.
You can use the deprecated Thread.stop() if you are sure there is no possible side effects. This requires using a plain Thread. Its not ideal even if you "know" this shouldn't cause a problem and again using a flag to stop the task is preferred.
I have a program where I compile java code a user types into a text field, and then run it. A run the code in a seperate thread, so that the GUI they use to input the source code doesn't get locked up.
The GUI has an abort button that should stop the thread. My issue is that I need to stop the compiling thread no matter what is going on inside of it, which means I must account for a case where the thread is caught in an infinite loop (due to user error), and it cannot properly end itself using a safe flag. I've read up on many solutions that involve using a flag of some kind, but they aren't available to me because of this looping issue. I need to have the thread stop and the memory it's using freed (I can't just let it sit in the background forever, unless that is the only solution left). Any advice or alternative solutions? Hopefully some fresh perspectives could help squash this issue.
Edit:
Here's a sample bit of user submitted code:
public class RunMe extends SomethingThatRuns {
public void run() {
int i = 0;
while (i = 0) {
//Prepare to get stuck!
}
}
}
I'll compile this class, and then run it. This is where it will get stuck, and the run() method can never finish, or even loop to check a flag.
You can run it in a new JVM so you can kill it when you want.
Thinking about security this may be a good thing to do too.
Call stop() on the thread.
Yes, this is a deprecated method. However, it really shouldn't be "deprecated", it should be "dangerous." In some circumstances, however, there's really no choice but to use it, and the invocation of an "agent" provided by a user is one of those cases.
Make sure that your program doesn't use any data that are manipulated by this user thread; or, if you do, devise some transactional mechanism to exchange data safely between the threads.
Even this method isn't guaranteed to terminate the thread. For example, the user can catch the resulting Throwable and ignore it. Or, the thread implementation might not respond to stop() calls if the thread is in some native code. But it's your best chance.
The core issue here is the fact that the code even allows an infinite loop to be entered as part of user error. Fix that, and everything else will become easier to deal with.
Properly-behaving threads should usually terminate themselves gracefully when there's no work to do (or return quietly to a thread pool to ask for more work, if that's your application's design). If you feel like you need to have one thread forcefully kill another then you've likely got a fundamental design issue. It's fine to have one thread tell another, "Hey, you should terminate now so that I can join with you..." because that allows your threads to clean things up as they finish. Forcefully destroying threads just isn't the right way to manage these situations.
You can use them to insert a interrputed check in every loop and maybe in other places too.
I can see two options:
As you compile the user code you can edit it before. You may use
ANTLR to parse and modify the code.
There are bytecode manipulation frameworks like ASM that allow you to manipulate code that is already
compiled.
I don't think it is easy but it might be a way.
interupt(); the Thread in the gui
and in the code that the thread runs regularly check for Thread.interrupted() and throw an exception when you do especially inside loops
At a high level, you are asking how one thread might go about stopping another thread. To that end, see this SO question Stopping a Thread in Java?.
I am currently using JMX to manage and monitor a huge migration process which is executed within a Java class.
I would like to be able to abort and kill the process when I needed, e.g. customer/time required, or some dead loop happens within a single migration.
Here, we call abort a gracefully way to kill a thread by setting up a boolean flag and once every loop will check the flag first and then decides whether to proceed or not. This has been implemented without any issue.
However, I am having troubles with kill the thread. My colleague had suggested me to override the finalize() method and try to kill it within it. However, what I have found online is this method will not be able to destroy the object and it is recommned to be called by GC but the user instead.
I guess the theory is OK that as long as the object is destroyed, no more process will be able to happen. I am just not sure whether this is able to be implemented in JAVA or not.
Also, I would like to know, is there any other ways that you guys can give me a hint.
Would be very appreciate your help.
P.S: by relating to JMX, doesn't mean it really has to do with JMX, it just I would like this killing command is coming from the JMX console client.
It's a bit hard to understand what you are saying, but I don't think that finalize is going to be any help.
A live thread (i.e. one that has been started and has not yet terminated) is reachable by definition, and therefore won't be garbage collected. So adding a finalize method to it won't have any affect.
If the object you are talking about is not the thread, adding a finalize probably won't help either:
If the thread's runnable (or whatever) has a reference to the object, that will stop it from being garbage collected.
If it doesn't, and the object does become unreachable, the finalize method won't run until after the GC has decided to collect the object ... and that may never happen.
Even if the finalize method did get called, what could it do? You've already told the thread to shut down ... and nothing has happened.
The real problem here seems to be that the thread is not responding to your "graceful shutdown" flag.
I'd try to fix this by using Thread.interrupt() and Thread.isInterrupted() rather than a custom flag. This has the advantage that an interrupt will also unblock things like Thread.sleep Object.wait and certain I/O operations.
If the thread is blocked trying to talk to some external service via a socket or pipe, you could unblock it by closing the socket and/or stream. This of course assumes that your shutdown code can get its hands on the reference to the Socket or Stream object.
If those approaches failed, I'd consider pulling the plug on the entire application by calling System.exit() ... if that's a reasonable thing to do.
If you are totally desperate (and a little bit insane) you could consider using the deprecated Thread.abort() method. But there is a distinct possibility that that would leave your entire application in a broken and unresponsive state. So I would NOT recommend this approach.
The other possibilities to consider are:
that the Thread has actually responded and exited, but your shutdown code didn't notice,
that the Thread died before you tried to shut it down it, and your shutdown code didn't notice,
that the Thread is deadlocked, or
that there is some long running (but not infinite) loop in the runnable needs to be modified to check the "you die now" flag more often.
Some of these things you could be diagnosed by attaching a debugger and taking a thread dump.
I think you said that you saw advice to the effect that it was a BAD IDEA to call System.gc(). This is good advice.
You should perform certain task in finally which you want to perform when method exits in any condition. Most preferable example people give about this is cosing database connection.
Yes it is recommended to leave Garbage Collection on JVM.
JVM takes care of destrying objects.
Up to now I used my application as a stand alone product. So, when user pressed "Stop" button I called System.exit(0); and it was fine.
Now my application will be called (in a programmatic way) from another program. So, I afraid that System.exit(0); will kill not only my process but also the external software which started my program.
So, what is the correct way to shutdown my application if a corresponding request from an external software is received? My application is an GUI application. So, I want to close the window but I also want to close all processes performed by my program.
ADDED:
To be more specific, I want to close all threads started by my program. My program does not start any OS process or any other program.
If the threads you've launched are still processing then calling System.exit(0) will cause them to be killed. In some cases, this can leave your application in an inconsistent state. Imagine that the thread was saving a file for example.
You should ensure that the your threads are all 'happy' to die before calling System.exit.
One technique you can use for this with long running threads is poisoning. To do this you send the threads a message that they should now die gracefully - i.e. a poson message. Once they have all died, it is safe to call System.exit(0) to terminate the Swing event handling thread.
There a loads of different ways of implementing poisoning, you could just set a global flag variable that the threads check to see if they've been poisoned, or you could use the Java 5 threading libraries. Take a look at this Javadoc for example and you'll find references to this technique:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
As long as your programm isn't sharing an application server with others, shuting down the VM by calling System.exit(0) terminates all threads.
From Javadoc
System.exit Terminates the currently running Java Virtual Machine)
EDIT:
If you want to do some clean up code before shutdown, http://java.sun.com/j2se/1.4.2/docs/guide/lang/hook-design.html
There is on "one-size-fits-all" answer to this that's a drop-in replacement for System.exit, unfortunately.
You will generally need to set some kind of flag that signals to all of your threads that it is time to exit, and ensure that they check this flag regularly. This will let them clean up gracefully without stopping abruptly, and it also ensures the effects are limited to your own components. In this case your application's main thread would also observe the flag, wait for all the "worker" type threads to finish and would then return all the way up the stack until your application's entry point was reached.
This question is not too dissimilar to the deprecated Thread.stop (etc) methods, especially with regards to replacing System.exit with something more respectful. In that light, the why is Thread.stop() deprecated page may be useful reading.
Throwing an exception (a custom one called something like ApplicationStopException) to unwind the stack of the main thread is not such a bad idea; this prevents you from having to handle the special logic all over your code and instead lets the "message" propagate to the higher levels, where they can take whatever action is needed to exit your program gracefully.
I recommend you to do flagging to stop the thread so that the thread will know when it has to stop. For GUI and window, you can call frame.dispose().
For System.exit(), I think it will not affect the caller, you may try to see what is the real effect but as other people already recommended, do not call it directly like that, just let the threads stop by itself