How to timeout a thread

后端 未结 17 1140
时光说笑
时光说笑 2020-11-22 01:01

I want to run a thread for some fixed amount of time. If it is not completed within that time, I want to either kill it, throw some exception, or handle it in some way. How

17条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-22 01:47

    I was looking for an ExecutorService that can interrupt all timed out Runnables executed by it, but found none. After a few hours I created one as below. This class can be modified to enhance robustness.

    public class TimedExecutorService extends ThreadPoolExecutor {
        long timeout;
        public TimedExecutorService(int numThreads, long timeout, TimeUnit unit) {
            super(numThreads, numThreads, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(numThreads + 1));
            this.timeout = unit.toMillis(timeout);
        }
    
        @Override
        protected void beforeExecute(Thread thread, Runnable runnable) {
            Thread interruptionThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // Wait until timeout and interrupt this thread
                        Thread.sleep(timeout);
                        System.out.println("The runnable times out.");
                        thread.interrupt();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            interruptionThread.start();
        }
    }
    

    Usage:

    public static void main(String[] args) {
    
        Runnable abcdRunnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("abcdRunnable started");
                try {
                    Thread.sleep(20000);
                } catch (InterruptedException e) {
                    // logger.info("The runnable times out.");
                }
                System.out.println("abcdRunnable ended");
            }
        };
    
        Runnable xyzwRunnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("xyzwRunnable started");
                try {
                    Thread.sleep(20000);
                } catch (InterruptedException e) {
                    // logger.info("The runnable times out.");
                }
                System.out.println("xyzwRunnable ended");
            }
        };
    
        int numThreads = 2, timeout = 5;
        ExecutorService timedExecutor = new TimedExecutorService(numThreads, timeout, TimeUnit.SECONDS);
        timedExecutor.execute(abcdRunnable);
        timedExecutor.execute(xyzwRunnable);
        timedExecutor.shutdown();
    }
    

提交回复
热议问题