取消正在执行的线程

Posted zhangjin1120

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了取消正在执行的线程相关的知识,希望对你有一定的参考价值。

Future调用cancel(true)后,仍然在执行?

开一个线程,执行一个任务:计算1000000033是不是质数,2秒后取消这个任务。
真的是:不试不知道,一试吓一跳!!!

public class FutureTest 

    public static void main(String[] args)
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        Future<Boolean> future = threadPool.submit(new Callable<Boolean>() 
            @Override
            public Boolean call()throws Exception 
                // i < num 让任务有足够的运行时间
                long num = 1000000033L;
                for (long i = 2; i < num; i++) 

                    if (num % i == 0) 
                        return false;
                     else if (i % 100000000 == 0) 
                        System.out.print("i=" + i + "  ");
                        if (i % 600000000 == 0) 
                            System.out.println("\\n");
                        
                    
                
                return true;
            
        );
        threadPool.shutdown(); // 发送关闭线程池的指令
        cancelTask(future, 2000); //2秒后取消任务

        try 
            boolean is = future.get();
            System.out.println("--------------------------------------------is:" + is + "-----------------------");
         catch (CancellationException ex) 
            System.err.println("\\n\\n\\n任务被取消\\n\\n\\n");
         catch (InterruptedException ex) 
            System.err.println("当前线程被中断");
         catch (ExecutionException ex) 
            System.err.println("任务执行出错");
        


    


    private static void cancelTask(Future<?> future, int delay) 
        new Thread(new Runnable() 
            @Override
            public void run() 
                try 
                    Thread.sleep(delay);
                    future.cancel(true); // 取消与 future 关联的正在运行的任务
                 catch (InterruptedException ex) 
                    ex.printStackTrace(System.err);
                
            
        ).start();
    


完整的取消方法

在for循环里面添加判断:

                    if (Thread.currentThread().isInterrupted())  // 任务被取消
                        System.out.println("PrimerTask.call: 你取消我干啥?");
                        return false;
                    

完整方法如下:

public class FutureTest 

    public static void main(String[] args)
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        Future<Boolean> future = threadPool.submit(new Callable<Boolean>() 
            @Override
            public Boolean call()throws Exception 
                // i < num 让任务有足够的运行时间
                long num = 1000000033L;
                for (long i = 2; i < num; i++) 
                    if (Thread.currentThread().isInterrupted())  // 任务被取消
                        System.out.println("PrimerTask.call: 你取消我干啥?");
                        return false;
                    
                    if (num % i == 0) 
                        return false;
                     else if (i % 100000000 == 0) 
                        System.out.print("i=" + i + "  ");
                        if (i % 600000000 == 0) 
                            System.out.println("\\n");
                        
                    
                
                return true;
            
        );
        threadPool.shutdown(); // 发送关闭线程池的指令
        cancelTask(future, 2000); //2秒后取消任务

        try 
            boolean is = future.get();
            System.out.println("--------------------------------------------is:" + is + "-----------------------");
         catch (CancellationException ex) 
            System.err.println("\\n\\n\\n任务被取消\\n\\n\\n");
         catch (InterruptedException ex) 
            System.err.println("当前线程被中断");
         catch (ExecutionException ex) 
            System.err.println("任务执行出错");
        


    


    private static void cancelTask(Future<?> future, int delay) 
        new Thread(new Runnable() 
            @Override
            public void run() 
                try 
                    Thread.sleep(delay);
                    future.cancel(true); // 取消与 future 关联的正在运行的任务
                 catch (InterruptedException ex) 
                    ex.printStackTrace(System.err);
                
            
        ).start();
    

看下运行效果:

以上是关于取消正在执行的线程的主要内容,如果未能解决你的问题,请参考以下文章

如何取消延迟的线程?

为啥任务取消发生在调用者线程上?

如何从另一个线程取消 GTK3 线程?

F# 线程中的取消标记

java 子线程 回调 主线程

并发编程:取消与关闭