Thread.stop() - deprecated
Asked Answered
C

6

63

Why is Thread.stop() deprecated in Java? On their website, I see the following:

Why is Thread.stop deprecated?

Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.

I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?

Clynes answered 12/5, 2013 at 4:16 Comment(1)
Monitors are a crucial concept for multi threaded control and communication. You should take the time to read through something like this to get a better understanding. Technically speaking, no, there isn't any sure way to stop any thread, event if it has internal mechanisms to allow for for it, as other parts of the libraries may not be monitoring the state of threadPhenylalanine
G
58

You asked:

My question is if theres no way to stop a thread in Java then how to stop a thread?

The Answer: In Java there's no clean, quick or reliable way to stop a thread.

Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?

Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.

To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.

Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/

Galosh answered 12/5, 2013 at 4:20 Comment(4)
Just to be sure, Or what about the monitor locks held by the thread when it is shot in the head it means that .stop can cause deadlocks?Simp
@Simp According to the documentation, it does not directly cause deadlocks. Instead, it unlocks the locks abruptly and unsafely. This can cause some data being damaged. Consider adding a new item to synchronized doubly linked list – you create a new record and update some references, but the thread is stopped before updating all of them. However, the lock is released when the thread is stopped, so iterating from the end does not show just reversed sequence of the elements (compared to iterating from the start).Phoenicia
Those inconsistencies might cause various strange behavior. Maybe deadlocks probably can be one of them, but probably not in the way you meant.Phoenicia
Got it, the damage is unpredictableSimp
K
9

When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:

class MyThread implements Runnable{
    @Override
    public void run() {
        for (int i = 1; i < 10000000; i++)
            try {
            System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
            if (Thread.interrupted()) 
                    throw new InterruptedException();
            } catch (InterruptedException e) {
                return;
        }   
    }
}

ExecutorService executor = Executors.newFixedThreadPool(3);
            executor.submit(new MyThread());
            executor.submit(new MyThread());
            executor.submit(new MyThread());
            executor.shutdownNow();

Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.

Kettle answered 11/11, 2014 at 18:40 Comment(1)
If still, you want to stop a particular thread you can use Future class cancel() method to signal the interruption.Vet
I
5

The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.

Thread exampleThread = new Thread(){
    public void run(){
        try {

            Thread.sleep(2000);

        } catch (InterruptedException ex) {
            //handle the exception
        }
    }
};

exampleThread.start();
exampleThread.join();

Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer. In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.

Impeach answered 12/5, 2013 at 4:23 Comment(5)
I know joins. What if the exampleThread never dies (e.g. infinite loop). I want to know how to kill exampleThread.Clynes
Well, usually you'd use a boolean flag that should be able to get the thread out of a loop. Otherwise you need to redesign, you shouldn't be have an infinite loop in the first place.Impeach
Why not? Say the Thread is receiving packets from the Client over the network and is supposed to be running all the time? How can I kill it externally?Clynes
Still if you want to be able to kill the thread at some point, you should have a flag that can signal to the thread that it needs to stop else there is no principled way.Impeach
You can use Thread.interrupt(). But anyway your thread has to be designed to respond to an interrupt #5915656Indigene
C
4

The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want. For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:

class StoppableThread implements Runnable {

    boolean isCancelled = false;


    public void run() {
        while (!isCancelled) {
            System.out.println("Thread is running with all its might!");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }   
    }


    public void cancel () {
        isCancelled = true;
    }
}
Chastity answered 11/2, 2020 at 10:54 Comment(0)
S
3

From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:

Most 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, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized ).

Slingshot answered 9/7, 2017 at 17:48 Comment(0)
D
-1

Threads in java are interesting because how you implement them depends on the purpose of the program you are writing. If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method. The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads... So this is one of the many reason why using thread.stop should be discouraged

Dioptase answered 28/8, 2022 at 8:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.