Stopping thread in Java
At the moment, Java has adopted a notification order for stopping a thread (although JDK 1.0 has several methods that control the execution of a thread, for example, stop(), suspend() and resume() - in the next versions of the JDK they were all marked as deprecated due to potential threats interlocking).
To correctly stop the thread, you can use the method of the Thread class - interrupt(). This method sets some internal interrupt status flag. Later, the state of this flag can be checked using the isInterrupted() or Thread.interrupted() method (for the current thread). The interrupt() method can also wake up a thread from a sleep or hibernation state. That is, if the sleep() or wait() methods were called on the thread, the current state will be interrupted and an InterruptedException will be thrown. The flag is not displayed in this case.
The scheme of action in this case is as follows:
- Implement a stream.
- Periodically check the interrupt status in the thread by calling isInterrupted().
- If the state of the flag has changed or an exception was thrown while waiting/hibernating, then the thread is trying to stop from outside.
- Make a decision - to continue working (if for some reason it is impossible to stop) or release the resources locked by the thread and finish execution.
A possible problem with this approach is blocking on stream I/O. If the thread is blocked on reading data, calling interrupt() will not get it out of this state. The solutions here differ depending on the type of data source. If reading is from a file, long-term blocking is extremely unlikely, and then you can simply wait for the read() method to exit. If the reading is somehow connected to the network, you should use non-blocking I/O from Java NIO.
The second option for implementing the stop method (as well as suspension) is to make your own analogue of interrupt(). That is, declare flags in the thread class - to stop and/or suspend and set them by calling predefined methods from outside. The method of action remains the same - check the setting of flags and make decisions when they change. Disadvantages of this approach. First, threads in a waiting state cannot be "revived" in this way. Secondly, setting the flag by one thread does not mean that the second thread will immediately see it. To improve performance, the virtual machine uses the data cache of the thread, as a result of which the update of the variable on the second thread can occur after an indefinite period of time (although a valid solution would be to declare the flag variable as volatile).
Why is it not recommended to use Thread.stop() method?
When forcibly stopping (suspending) a thread, stop() interrupts the thread in a non-deterministic place of execution, as a result it becomes completely unclear what to do with the resources belonging to it. A stream can open a network connection - then what to do with data that has not yet been read? Where is the guarantee that after the further start of the stream (in case of suspension) he will be able to finish reading them? If a thread has blocked a shared resource, then how to release this lock and will a forced release lead to a violation of system consistency? The same can be extended to the case of a database connection: if the thread is stopped in the middle of a transaction, who will close it? Who will unlock resources and how?
Read also:
- Race condition in Java
- Runnable, Callable, FutureTask, CyclicBarrier and CountDownLatch in Java
- Keywords volatile, synchronized, transient, native in Java
Comments
Post a Comment