📜 ⬆️ ⬇️

Java. Stop the task

For nearly a year I have been hard at work on Java coding. Faced a rather serious problem in my opinion related to multithreading, it seems to me, insoluble in the framework of the current implementation of JVM from Oracle (this applies to JDK 1.5 and higher). The fact is that at the moment in Java there is no way to safely stop the execution of any thread. This post explains why this is exactly what proposes to start a discussion on how to solve this problem.

It would seem a trivial task: we have some Thread (flow), which, we know for sure, is hopelessly frozen (it may be looped, maybe something else), while consuming some resources. What should we do with it? I would like to free our resources. It would seem that easier? But no, a detailed study of the issue turned out that the JVM simply did not have instructions for correctly stopping the hung thread. The old Thread.stop () method has been declared deprecated and committed to the strictest anathema. As stated in javadoc, this method is “essentially unsafe.” Well, if we are not safe, we will not use it; give us another, safe method. But another safe oddly is not offered. Of course, a very safe Thread.interrupt () instruction is proposed. But it is safe, unfortunately, because absolutely nothing does! This is just a message to the stream: "Please stop." But if the thread ignored this message, then ... as stated in the documentation “If the thread does not respond to Thread.interrupt (), you can use tricks specific to your application”. Thank you for allowing. What is called, spin as you want.

Everything becomes even more complicated if the task is running in the thread pool, through, for example, ExecutorService.submit (Runnable) . At the same time, we don’t even know in which particular thread this task is performed and can no longer even use the forbidden Thread.stop (). On the other hand, we have a reference to Future , and Future has a method Future.cancel (boolean) , which should cancel the execution of the task. But if the task has already started, calling Future.cancel (true) will not actually stop it. In the depths of the FutureTask implementation , the following code is executed:

if (mayInterruptIfRunning) {
Thread r = runner;
if (r != null)
r.interrupt(); }

Those. again, the thread in which the task is executed is only recommended to stop execution. In addition, we do not even have the opportunity to know whether the task is being carried out at the moment or not. There is, it seems, the Future.isDone () method, but again by, it returns true not only when the task has completed, but immediately after calling Future.cancel (), even if the task is still running (after all, Future.cancel (true) does not stops the task that has already started running).
')
Well, if we write all the code ourselves, then we can accurately handle Thread.isInterrupted () in the right places and everything will be OK. But if we run third-party code? If we have a server extensible with plugins? Any crookedly written plug-in can easily lead to an inoperative state of the entire server because we cannot correctly interrupt the execution of a hung plug-in.

I admit, I do not know a satisfactory solution. Maybe the Thread.stop () method is not so dangerous? I'd love to hear the opinions of Java programmers practitioners on this.

Source: https://habr.com/ru/post/133413/


All Articles