Thread.stop() is now removed from modern Android API. From https://developer.android.com/reference/java/lang/Thread#stop(),
Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, ...
I suppose that a complete removal of a method must be backed by an alternative of it, both for the many uses where it is replaceable, and for the many other uses where it is not. I am therefore wondering what is the alternative of Thread.stop() that stops a thread where cooperative interruption flags do not work, which is possibly due to e.g. calls of slow 3rd-party functions.
From the articles I've googled and the duplicated SO questions I've read about this issue, I got only two unsatisfactory types of answers:
You should just consider cooperative interruption because it's not stupid.
Thread.stop() is now gone for whatever reason so just forget it.
I would appreciate a lot if you could either provide a functioning alternative of Thread.stop() or explain the rationale behind removing it despite the legitimate use cases depending on it, where "legitimate" implies nonexistence of any synchronization and locking issue.
Thanks in advance.
There is no "modern" alternative. The old alternatives are still the only ones. Why? Because this is fundamentally an unsolvable problem1 ... if the threads are not cooperating / checking for thread interrupts, or if they unable to correctly deal with a thread interrupt.
For the record, the technical reasons that Thread.stop() is unsafe include:
It breaks mutual exclusion locks help by the thread being stopped. This may leave the object that was locked ... or other objects ... in an inconsistent state.
It may result in broken inter-thread signalling. For example, if a thread is expected to notify a condition variable, and it gets stopped before this happen, then other threads may be stuck forever waiting for a notify that never arrives.
If has said that, issues such as the above can in theory be addressed by application code on a case-by-base basis. For example, if you were using stop() you could catching ThreadDeath in all of the necessary places, take remedial action and then rethrow it. But to borrow someone else's words, "it would be insanely messy".
I'm sorry if you think this is all unsatisfactory. But this is life. If you cannot write your threads to be cooperative, and you need them to be killable, run them in an external process, via Process etcetera.
Now ... if we could wave a magic wand and replace Java threads with a CSP-like model of concurrency (and in doing so, eschew state sharing between processes), then the problem goes away. Though now you have to deal with the other problem of what to do with the messages queued up when a process is terminated. But at least that is a tractable problem.
1 - I am asserting this without proof! However, if it was a solvable problem, then you would have thought that Sun or Oracle or Google would have discovered and implemented a solution in the last ... umm ... 25 years. Challenge: If you can come up with a viable implementation model for safely killing Java threads, I expect that certain companies would be willing to offer you a very well-paid job. Especially if they can secure exclusive rights on your patent.
Summary
From my studies, I don't remember that a concept such "uninterruptible block" exists, and I did not find it either with a quick Google search.
Expected answer
yes, it does exist, and the proper term for that is ... (in this case, it would be nice, if someone could explain me, why it does not exist in Java)
no, it does not exist, because ...
Definition
By "uninterruptible block", I mean a section of code, in a multi-threading context, which, once starts execution, cannot be interrupted by other threads. I.e., the CPU (or the JVM), won't run any other thread at all, until the "atomic block" is left.
Note, that this is not the same as a section marked by lock/mutex/... etc., because such section can not be interrupted only by other threads, which acquire the same lock or mutex. But other threads can still interrupt it.
EDIT, in response to comments It would be fine also, if it affected only the threads of the current process.
RE. multiple cores: I would say, yes, also the other cores should stop, and we accept the performance hit (or, if it is exclusive only for the current process, then the other cores could still run threads of other processes).
Background
First of all, it is clear, that, at least in Java, this concept does not exist:
Atomic as in uninterruptible: once the block starts, it can't be interrupted, even by task switching.
...
[this] cannot be guaranteed in Java - it doesn't provide access to the
"critical sections" primitives required for uninterruptibility.
However, it would have come in handy in the following case: a system sends a request and receives response A. After receiving the response, it has max. 3 seconds to send request B. Now, if multiple threads are running, doing this, then it can happen, that after receiving response A, the thread is interrupted, and one or more threads run, before the original thread has the chance to send out request B, and thus misses the 3 seconds deadline. The more threads are running, the bigger the risk that this happens. By marking the "receive A to send B" section "uninterruptible", this could be avoided.
Note, that locking this section would not solve the issue. (It would not prevent the JVM, from e.g. processing 10 new threads at the "send request A" phase, right after our thread received response A.)
EDIT: Re. global mutex. That would also not solve the issue. Basically, I want the threads to make Request A's (and some other stuff) simultaneously, but I want them to stop, when another thread received Response A, and is going to make Request B.
Now, I know, that this would not be a 100% solution either, because those threads that don't get scheduled right after receiving response A still could miss the deadline. But, at least, those who do, would for sure send out the second request in time.
Some further speculation
The classic concurrency problem a++ could be simply solved by uninterruptible { a++; }, without the need for locks (which can cause dead-lock, and, in any case, would probably be more expensive in terms of performance, than simply executing the three instructions required by a++, with a simple flag, that they must not be interrupted).
EDIT RE. CAS: of course, that's another solution too. However, it involves retrying, until the write succeeds, and it is also slightly more complex to use (at least in Java, we have to use AtomicXXX, instead of the primitive types for that).
I know, of course, that this could be easily abused, by marking large blocks of code as uninterruptible, but that is true for many concurrency primitives as well. (What's more, I also know, that my original use case would be also kind of an "abuse", since I'd be doing I/O in an uninterruptible block, still it would have been worth at least a try, if such concept did exist in Java.)
The prevailing religion of Java today heavily forbids the use of the stop() instance method on a Thread[1] [2] [3]. It's marked as Deprecated in the official documentation, with a message that begins with:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. [...]
There is even a whole article supplied that goes into further detail. (Especially that ThreadDeath is silent when it gets to the top, and even if you guard against it, you can't guard against Thread.stop(Throwable t) anyway.)
In general, I agree with what that article is worried about, and with the answers to the related question on StackOverflow — in almost all the use cases in the world there is a much better way than stop(). But not all.
Here is a use case that I'm struggling to think of a better way for. I invite your suggestions.
Use case
I'm working with an interactive console running on top of Java, that allows the user run arbitrary Java statements and Python functions that call Java, in an interactive interpreted way. (See Jython console for screenshots.)
Now, the user can write arbitrary functions. Some of them might call Java methods that result in infinite loops that print a lot of output, almost saturating the system, so that it becomes painfully slow to respond.
When the user messes up like this, I need to give them a chance to kill the thread (using a button), and salvage the remainder of the work that they have produced in their session and stored in local variables.
If calling interrupt() on the thread fails, (e.g. if it never goes into waiting state while stuck in its infinite loop), then we are faced with two options that I can see: (1) kill the application outright or (2) use stop() on the bad thread, and let the user salvage whatever is left that hadn't been corrupted.
Yes I know that some objects may have been damaged and won't work properly. But we're talking about salvaging anything that may have been left in a valid state (which is probably pretty much everything, except one or two things).
Can anybody see any problems with this reasoning? And if this turns out to be a valid use-case, then does it mean the method shouldn't be deprecated :) ?
Calling Thread.stop() is a bad idea. End of story.
It may work in practice but you sacrifice most of the JVM's concurrency guarantees in the process. Your whole program is essentially running undefined behavior. It isn't simply the thread or the data in the thread that may become corrupted, but any part of the JVM that happens to be in a vulnerable state when the thread is killed.
It sounds like you're looking for someone to confirm that your use case somehow avoids the risks to the JVM. It doesn't, so you're not likely to get such a confirmation. If you don't see issues more power to you, but don't be surprised when it fails in inexplicable or dangerous ways.
As Peter Lawrey suggests you should be running this untrusted code in an isolated JVM, where the OS's process management can support killing resource-hogging processes. If you can't do that because you're passing around strange resources like open file descriptors that is your problem.
Is there a destructor for Java? I don't seem to be able to find any documentation on this. If there isn't, how can I achieve the same effect?
To make my question more specific, I am writing an application that deals with data and the specification say that there should be a 'reset' button that brings the application back to its original just launched state. However, all data have to be 'live' unless the application is closed or reset button is pressed.
Being usually a C/C++ programmer, I thought this would be trivial to implement. (And hence I planned to implement it last.) I structured my program such that all the 'reset-able' objects would be in the same class so that I can just destroy all 'live' objects when a reset button is pressed.
I was thinking if all I did was just to dereference the data and wait for the garbage collector to collect them, wouldn't there be a memory leak if my user repeatedly entered data and pressed the reset button? I was also thinking since Java is quite mature as a language, there should be a way to prevent this from happening or gracefully tackle this.
Because Java is a garbage collected language you cannot predict when (or even if) an object will be destroyed. Hence there is no direct equivalent of a destructor.
There is an inherited method called finalize, but this is called entirely at the discretion of the garbage collector. So for classes that need to explicitly tidy up, the convention is to define a close method and use finalize only for sanity checking (i.e. if close has not been called do it now and log an error).
There was a question that spawned in-depth discussion of finalize recently, so that should provide more depth if required...
Have a look at the try-with-resources statement. For example:
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
System.out.println(br.readLine());
} catch (Exception e) {
...
} finally {
...
}
Here the resource that is no longer needed is freed in the BufferedReader.close() method. You can create your own class that implements AutoCloseable and use it in a similar fashion.
This statement is more limited than finalize in terms of code structuring, but at the same time it makes the code simpler to understand and maintain. Also, there is no guarantee that a finalize method is called at all during the livetime of the application.
Nope, no destructors here. The reason is that all Java objects are heap allocated and garbage collected. Without explicit deallocation (i.e. C++'s delete operator) there is no sensible way to implement real destructors.
Java does support finalizers, but they are meant to be used only as a safeguard for objects holding a handle to native resources like sockets, file handles, window handles, etc. When the garbage collector collects an object without a finalizer it simply marks the memory region as free and that's it. When the object has a finalizer, it's first copied into a temporary location (remember, we're garbage collecting here), then it's enqueued into a waiting-to-be-finalized queue and then a Finalizer thread polls the queue with very low priority and runs the finalizer.
When the application exits, the JVM stops without waiting for the pending objects to be finalized, so there practically no guarantees that your finalizers will ever run.
Use of finalize() methods should be avoided. They are not a reliable mechanism for resource clean up and it is possible to cause problems in the garbage collector by abusing them.
If you require a deallocation call in your object, say to release resources, use an explicit method call. This convention can be seen in existing APIs (e.g. Closeable, Graphics.dispose(), Widget.dispose()) and is usually called via try/finally.
Resource r = new Resource();
try {
//work
} finally {
r.dispose();
}
Attempts to use a disposed object should throw a runtime exception (see IllegalStateException).
EDIT:
I was thinking, if all I did was just
to dereference the data and wait for
the garbage collector to collect them,
wouldn't there be a memory leak if my
user repeatedly entered data and
pressed the reset button?
Generally, all you need to do is dereference the objects - at least, this is the way it is supposed to work. If you are worried about garbage collection, check out Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning (or the equivalent document for your JVM version).
With Java 1.7 released, you now have the additional option of using the try-with-resources block. For example,
public class Closeable implements AutoCloseable {
#Override
public void close() {
System.out.println("closing...");
}
public static void main(String[] args) {
try (Closeable c = new Closeable()) {
System.out.println("trying...");
throw new Exception("throwing...");
}
catch (Exception e) {
System.out.println("catching...");
}
finally {
System.out.println("finalizing...");
}
}
}
If you execute this class, c.close() will be executed when the try block is left, and before the catch and finally blocks are executed. Unlike in the case of the finalize() method, close() is guaranteed to be executed. However, there is no need of executing it explicitly in the finally clause.
I fully agree to other answers, saying not to rely on the execution of finalize.
In addition to try-catch-finally blocks, you may use Runtime#addShutdownHook (introduced in Java 1.3) to perform final cleanups in your program.
That isn't the same as destructors are, but one may implement a shutdown hook having listener objects registered on which cleanup methods (close persistent database connections, remove file locks, and so on) can be invoked - things that would normally be done in destructors.
Again - this is not a replacement for destructors but in some cases, you can approach the wanted functionality with this.
The advantage of this is having deconstruction behavior loosely coupled from the rest of your program.
No, java.lang.Object#finalize is the closest you can get.
However, when (and if) it is called, is not guaranteed.
See: java.lang.Runtime#runFinalizersOnExit(boolean)
I agree with most of the answers.
You should not depend fully on either finalize or ShutdownHook
finalize
The JVM does not guarantee when this finalize() method will be invoked.
finalize() gets called only once by GC thread. If an object revives itself from finalizing method, then finalize will not be called again.
In your application, you may have some live objects, on which garbage collection is never invoked.
Any Exception that is thrown by the finalizing method is ignored by the GC thread
System.runFinalization(true) and Runtime.getRuntime().runFinalization(true) methods increase the probability of invoking finalize() method but now these two methods have been deprecated. These methods are very dangerous due to lack of thread safety and possible deadlock creation.
shutdownHooks
public void addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
A shutdown hook is simply an initialized but non-started thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled.
Finally, the virtual machine will halt. Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if the shutdown was initiated by invoking the exit method.
Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit.
But even Oracle documentation quoted that
In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly
This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.
Conclusion : use try{} catch{} finally{} blocks appropriately and release critical resources in finally(} block. During release of resources in finally{} block, catch Exception and Throwable.
First, note that since Java is garbage-collected, it is rare to need to do anything about object destruction. Firstly because you don't usually have any managed resources to free, and secondly because you can't predict when or if it will happen, so it's inappropriate for things that you need to occur "as soon as nobody is using my object any more".
You can be notified after an object has been destroyed using java.lang.ref.PhantomReference (actually, saying it has been destroyed may be slightly inaccurate, but if a phantom reference to it is queued then it's no longer recoverable, which usually amounts to the same thing). A common use is:
Separate out the resource(s) in your class that need to be destructed into another helper object (note that if all you're doing is closing a connection, which is a common case, you don't need to write a new class: the connection to be closed would be the "helper object" in that case).
When you create your main object, create also a PhantomReference to it. Either have this refer to the new helper object, or set up a map from PhantomReference objects to their corresponding helper objects.
After the main object is collected, the PhantomReference is queued (or rather it may be queued - like finalizers there is no guarantee it ever will be, for example if the VM exits then it won't wait). Make sure you're processing its queue (either in a special thread or from time to time). Because of the hard reference to the helper object, the helper object has not yet been collected. So do whatever cleanup you like on the helper object, then discard the PhantomReference and the helper will eventually be collected too.
There is also finalize(), which looks like a destructor but doesn't behave like one. It's usually not a good option.
The finalize() function is the destructor.
However, it should not be normally used because it is invoked after the GC and you can't tell when that will happen (if ever).
Moreover, it takes more than one GC to deallocate objects that have finalize().
You should try to clean up in the logical places in your code using the try{...} finally{...} statements!
If it's just memory you are worried about, don't. Just trust the GC it does a decent job. I actually saw something about it being so efficient that it could be better for performance to create heaps of tiny objects than to utilize large arrays in some instances.
Perhaps you can use a try ... finally block to finalize the object in the control flow at which you are using the object. Of course it doesn't happen automatically, but neither does destruction in C++. You often see closing of resources in the finally block.
There is a #Cleanup annotation in Lombok that mostly resembles C++ destructors:
#Cleanup
ResourceClass resource = new ResourceClass();
When processing it (at compilation time), Lombok inserts appropriate try-finally block so that resource.close() is invoked, when execution leaves the scope of the variable. You can also specify explicitly another method for releasing the resource, e.g. resource.dispose():
#Cleanup("dispose")
ResourceClass resource = new ResourceClass();
The closest equivalent to a destructor in Java is the finalize() method. The big difference to a traditional destructor is that you can't be sure when it'll be called, since that's the responsibility of the garbage collector. I'd strongly recommend carefully reading up on this before using it, since your typical RAIA patterns for file handles and so on won't work reliably with finalize().
Just thinking about the original question... which, I think we can conclude from all the other learned answers, and also from Bloch's essential Effective Java, item 7, "Avoid finalizers", seeks the solution to a legitimate question in a manner which is inappropriate to the Java language...:
... wouldn't a pretty obvious solution to do what the OP actually wants be to keep all your objects which need to be reset in a sort of "playpen", to which all other non-resettable objects have references only through some sort of accessor object...
And then when you need to "reset" you disconnect the existing playpen and make a new one: all the web of objects in the playpen is cast adrift, never to return, and one day to be collected by the GC.
If any of these objects are Closeable (or not, but have a close method) you could put them in a Bag in the playpen as they are created (and possibly opened), and the last act of the accessor before cutting off the playpen would be to go through all the Closeables closing them... ?
The code would probably look something like this:
accessor.getPlaypen().closeCloseables();
accessor.setPlaypen( new Playpen() );
closeCloseables would probably be a blocking method, probably involving a latch (e.g. CountdownLatch), to deal with (and wait as appropriate for) any Runnables/Callables in any threads specific to the Playpen to be ended as appropriate, in particular in the JavaFX thread.
Many great answers here, but there is some additional information about why you should avoid using finalize().
If the JVM exits due to System.exit() or Runtime.getRuntime().exit(), finalizers will not be run by default. From Javadoc for Runtime.exit():
The virtual machine's shutdown sequence consists of two phases. In the first phase all registered shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish. In the second phase all uninvoked finalizers are run if finalization-on-exit has been enabled. Once this is done the virtual machine halts.
You can call System.runFinalization() but it only makes "a best effort to complete all outstanding finalizations" – not a guarantee.
There is a System.runFinalizersOnExit() method, but don't use it – it's unsafe, deprecated long ago.
If you got the chance of using a Contexts and Dependency Injection (CDI) framework such as Weld you can use the Java annotation #Predestroy for doing cleanup jobs etc.
#javax.enterprise.context.ApplicationScoped
public class Foo {
#javax.annotation.PreDestroy
public void cleanup() {
// do your cleanup
}
}
Though there have been considerable advancements in Java's GC technology, you still need to be mindful of your references. Numerous cases of seemingly trivial reference patterns that are actually rats nests under the hood come to mind.
From your post it doesn't sound like you're trying to implement a reset method for the purpose of object reuse (true?). Are your objects holding any other type of resources that need to be cleaned up (i.e., streams that must be closed, any pooled or borrowed objects that must be returned)? If the only thing you're worried about is memory dealloc then I would reconsider my object structure and attempt to verify that my objects are self contained structures that will be cleaned up at GC time.
If you're writing a Java Applet, you can override the Applet "destroy()" method. It is...
* Called by the browser or applet viewer to inform
* this applet that it is being reclaimed and that it should destroy
* any resources that it has allocated. The stop() method
* will always be called before destroy().
Obviously not what you want, but might be what other people are looking for.
No Java doesn't have any destructors .The main reason behind it in Java is the Garbage Collectors that passively works in the background always and all the objects are made in the heap memory , that is the place where GC works .In c++ there we have to explicitly call the delete function since there is no Garbage collector like thing.
In Java, the garbage collector automatically deletes the unused objects to free up the memory. So it’s sensible Java has no destructors available.
Try calling the onDestroy() method when it comes to android programming. This is the last method that executed just before the Activity/Service class is killed.
Missing form all the answers I just scanned is the safer replacement for finalizers. All of the other answers are correct about using try-with-resources and avoiding finalizers as they are unreliable and are now deprecated...
However they haven't mentioned Cleaners. Cleaners were added in Java 9 to explicitly handle the job of cleanup in a better way than finalizers.
https://docs.oracle.com/javase/9/docs/api/java/lang/ref/Cleaner.html
I used to mainly deal with C++ and that is what lead me to the search of a destructor as well. I am using JAVA a lot now. What I did, and it may not be the best case for everyone, but I implemented my own destructor by reseting all the values to either 0 or there default through a function.
Example:
public myDestructor() {
variableA = 0; //INT
variableB = 0.0; //DOUBLE & FLOAT
variableC = "NO NAME ENTERED"; //TEXT & STRING
variableD = false; //BOOL
}
Ideally this won't work for all situations, but where there are global variables it will work as long as you don't have a ton of them.
I know I am not the best Java programmer, but it seems to be working for me.