简体   繁体   中英

Thread.stop() - deprecated

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?

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/

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.

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.

Fromhttps://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 ).

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;
    }
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM