How to properly stop the Thread in Java?

后端 未结 9 1038
执念已碎
执念已碎 2020-11-21 16:19

I need a solution to properly stop the thread in Java.

I have IndexProcessorclass which implements the Runnable interface:

public class          


        
相关标签:
9条回答
  • 2020-11-21 16:45

    For synchronizing threads I prefer using CountDownLatch which helps threads to wait until the process being performed complete. In this case, the worker class is set up with a CountDownLatch instance with a given count. A call to await method will block until the current count reaches zero due to invocations of the countDown method or the timeout set is reached. This approach allows interrupting a thread instantly without having to wait for the specified waiting time to elapse:

    public class IndexProcessor implements Runnable {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
    
        private final CountDownLatch countdownlatch;
        public IndexProcessor(CountDownLatch countdownlatch) {
            this.countdownlatch = countdownlatch;
        }
    
    
        public void run() {
            try {
                while (!countdownlatch.await(15000, TimeUnit.MILLISECONDS)) {
                    LOGGER.debug("Processing...");
                }
            } catch (InterruptedException e) {
                LOGGER.error("Exception", e);
                run = false;
            }
    
        }
    }
    

    When you want to finish execution of the other thread, execute countDown on the CountDownLatch and join the thread to the main thread:

    public class SearchEngineContextListener implements ServletContextListener {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(SearchEngineContextListener.class);
    
        private Thread thread = null;
        private IndexProcessor runnable = null;
        private CountDownLatch countdownLatch = null;
    
        @Override
        public void contextInitialized(ServletContextEvent event) {
            countdownLatch = new CountDownLatch(1);
            Thread thread = new Thread(new IndexProcessor(countdownLatch));
            LOGGER.debug("Starting thread: " + thread);
            thread.start();
            LOGGER.debug("Background process successfully started.");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent event) {
            LOGGER.debug("Stopping thread: " + thread);
            if (countdownLatch != null) 
            {
                countdownLatch.countDown();
            } 
            if (thread != null) {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    LOGGER.error("Exception", e);
                }
                LOGGER.debug("Thread successfully stopped.");
            } 
        }
    }
    
    0 讨论(0)
  • 2020-11-21 16:48

    Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():

    Thread t = new Thread(new Runnable(){
            @Override
            public void run() {
                while(!Thread.currentThread().isInterrupted()){
                    // do stuff         
                }   
            }});
        t.start();
    
        // Sleep a second, and then interrupt
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {}
        t.interrupt();
    

    ref- How can I kill a thread? without using stop();

    0 讨论(0)
  • 2020-11-21 16:48

    Some supplementary info. Both flag and interrupt are suggested in the Java doc.

    https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

    private volatile Thread blinker;
    
    public void stop() {
        blinker = null;
    }
    
    public void run() {
        Thread thisThread = Thread.currentThread();
        while (blinker == thisThread) {
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e){
            }
            repaint();
        }
    }
    

    For a thread that waits for long periods (e.g., for input), use Thread.interrupt

    public void stop() {
         Thread moribund = waiter;
          waiter = null;
          moribund.interrupt();
     }
    
    0 讨论(0)
提交回复
热议问题