How do you kill a Thread in Java?

前端 未结 16 1901
天命终不由人
天命终不由人 2020-11-21 05:54

How do you kill a java.lang.Thread in Java?

相关标签:
16条回答
  • 2020-11-21 06:39

    Attempts of abrupt thread termination are well-known bad programming practice and evidence of poor application design. All threads in the multithreaded application explicitly and implicitly share the same process state and forced to cooperate with each other to keep it consistent, otherwise your application will be prone to the bugs which will be really hard to diagnose. So, it is a responsibility of developer to provide an assurance of such consistency via careful and clear application design.

    There are two main right solutions for the controlled threads terminations:

    • Use of the shared volatile flag
    • Use of the pair of Thread.interrupt() and Thread.interrupted() methods.

    Good and detailed explanation of the issues related to the abrupt threads termination as well as examples of wrong and right solutions for the controlled threads termination can be found here:

    https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

    0 讨论(0)
  • 2020-11-21 06:40

    Generally you don't..

    You ask it to interrupt whatever it is doing using Thread.interrupt() (javadoc link)

    A good explanation of why is in the javadoc here (java technote link)

    0 讨论(0)
  • 2020-11-21 06:41

    There is no way to gracefully kill a thread.

    You can try to interrupt the thread, one commons strategy is to use a poison pill to message the thread to stop itself

    public class CancelSupport {
        public static class CommandExecutor implements Runnable {
                private BlockingQueue<String> queue;
                public static final String POISON_PILL  = “stopnow”;
                public CommandExecutor(BlockingQueue<String> queue) {
                        this.queue=queue;
                }
                @Override
                public void run() {
                        boolean stop=false;
                        while(!stop) {
                                try {
                                        String command=queue.take();
                                        if(POISON_PILL.equals(command)) {
                                                stop=true;
                                        } else {
                                                // do command
                                                System.out.println(command);
                                        }
                                } catch (InterruptedException e) {
                                        stop=true;
                                }
                        }
                        System.out.println(“Stopping execution”);
                }
    
        }
    

    }

    BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
    Thread t=new Thread(new CommandExecutor(queue));
    queue.put(“hello”);
    queue.put(“world”);
    t.start();
    Thread.sleep(1000);
    queue.put(“stopnow”);
    

    http://anandsekar.github.io/cancel-support-for-threads/

    0 讨论(0)
  • 2020-11-21 06:41

    Thread.stop is deprecated so how do we stop a thread in java ?

    Always use interrupt method and future to request cancellation

    1. When the task responds to interrupt signal, for example, blocking queue take method.
    Callable < String > callable = new Callable < String > () {
        @Override
        public String call() throws Exception {
            String result = "";
            try {
                //assume below take method is blocked as no work is produced.
                result = queue.take();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return result;
        }
    };
    Future future = executor.submit(callable);
    try {
        String result = future.get(5, TimeUnit.SECONDS);
    } catch (TimeoutException e) {
        logger.error("Thread timedout!");
        return "";
    } finally {
        //this will call interrupt on queue which will abort the operation.
        //if it completes before time out, it has no side effects
        future.cancel(true);
    }
    
    
    1. When the task does not respond to interrupt signal.Suppose the task performs socket I/O which does not respond to interrupt signal and thus using above approach will not abort the task, future would time out but the cancel in finally block will have no effect, thread will keep on listening to socket. We can close the socket or call close method on connection if implemented by pool.
    public interface CustomCallable < T > extends Callable < T > {
        void cancel();
        RunnableFuture < T > newTask();
    }
    
    public class CustomExecutorPool extends ThreadPoolExecutor {
        protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
            if (callable instanceof CancellableTask)
                return ((CancellableTask < T > ) callable).newTask();
            else
                return super.newTaskFor(callable);
        }
    }
    
    public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
        public synchronized void cancel() {
            try {
                obj.close();
            } catch (IOException e) {
                logger.error("io exception", e);
            }
        }
    
        public RunnableFuture < T > newTask() {
            return new FutureTask < T > (this) {
                public boolean cancel(boolean mayInterruptIfRunning) {
                    try {
                        this.cancel();
                    } finally {
                        return super.cancel(mayInterruptIfRunning);
                    }
                }
    
            };
        }
    }
    
    0 讨论(0)
  • 2020-11-21 06:48

    In Java threads are not killed, but the stopping of a thread is done in a cooperative way. The thread is asked to terminate and the thread can then shutdown gracefully.

    Often a volatile boolean field is used which the thread periodically checks and terminates when it is set to the corresponding value.

    I would not use a boolean to check whether the thread should terminate. If you use volatile as a field modifier, this will work reliable, but if your code becomes more complex, for instead uses other blocking methods inside the while loop, it might happen, that your code will not terminate at all or at least takes longer as you might want.

    Certain blocking library methods support interruption.

    Every thread has already a boolean flag interrupted status and you should make use of it. It can be implemented like this:

    public void run() {
       try {
          while (!interrupted()) {
             // ...
          }
       } catch (InterruptedException consumed)
          /* Allow thread to exit */
       }
    }
    
    public void cancel() { interrupt(); }
    

    Source code adapted from Java Concurrency in Practice. Since the cancel() method is public you can let another thread invoke this method as you wanted.

    0 讨论(0)
  • 2020-11-21 06:50

    I didn't get the interrupt to work in Android, so I used this method, works perfectly:

    boolean shouldCheckUpdates = true;
    
    private void startupCheckForUpdatesEveryFewSeconds() {
        Thread t = new Thread(new CheckUpdates());
        t.start();
    }
    
    private class CheckUpdates implements Runnable{
        public void run() {
            while (shouldCheckUpdates){
                //Thread sleep 3 seconds
                System.out.println("Do your thing here");
            }
        }
    }
    
     public void stop(){
            shouldCheckUpdates = false;
     }
    
    0 讨论(0)
提交回复
热议问题