• 线程池(5)-停止线程池里的任务


    1.问题

    当我们认为某个任务执行时间太长了,想要停止这个任务,在线程池里应该如何实现呢?

    2.不用线程池如何停止一个线程

    停止线程池里的任务等同于停止一个线程,所以我们需要先了解如何停止一个线程。

    网上很多博客写了停止一个线程解决方法,停止一个线程有三种方法。

    2.1使用标识

    示例:

        static volatile boolean flag = true;
    
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (flag) {
                            Thread.sleep(1000);
                            System.err.println("print a");
                        }
                    } catch (InterruptedException e) {
                        System.err.println("我是在sleep interrupted");
                    }
                }
            }, "t1");
            thread.start();
            Thread.sleep(5000);
            flag = false;
        }

    注意使用volatile关键字

    2.2使用stop

    作废,不用关心了

    2.3使用interrupt

    示例:

        public static void main(String[] args) throws Exception {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (true) {
                            Thread.sleep(1000);
                            //写了sleep就不用写下面的判断
                            if (Thread.currentThread().isInterrupted()) {
                                throw new InterruptedException();
                            }
                            System.err.println("print a");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "t1");
            thread.start();
            Thread.sleep(20);
            thread.interrupt();
        }

    3.停止线程池里的任务

    按照停止线程方法,停止线程池里的任务有两种方法(stop作废)

    3.1使用标识

    这儿不贴代码了,思路比较简单,使用全局的Map存任务名与是否停止,在任务里判断。

    3.2使用interrupt

    示例:

    public class ThreadPoolStopThread {
        static class MyRunnable implements Runnable {
    
            private String jobName;
            private Thread nowThread;
    
            MyRunnable(String jobName) {
                this.jobName = jobName;
            }
    
            public void setInterrupted() {
                nowThread.interrupt();
            }
    
            @Override
            public void run() {
                nowThread = Thread.currentThread();
                try {
                    while (true) {
                        Thread.sleep(1000);
                        // 写了sleep就不用再判断isInterrupted()了
                        System.err.println("当前线程:" + Thread.currentThread().getName() + " 当前任务:" + jobName);
                    }
                } catch (InterruptedException e) {
                    System.err.println("当前线程:" + Thread.currentThread().getName() + " 当前任务:" + jobName + "马上停止");
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService es = Executors.newFixedThreadPool(2, new MyThreadFactory());
            MyRunnable job1 = new MyRunnable("job-1");
            MyRunnable job2 = new MyRunnable("job-2");
            MyRunnable job3 = new MyRunnable("job-3");
            es.execute(job1);
            es.execute(job2);
            es.execute(job3);
            System.err.println("5s后停止job-1");
            Thread.sleep(5000);
            job1.setInterrupted();
        }
    }
  • 相关阅读:
    「CSP-S 2019」初赛解析
    「SP741」STEAD
    「CF1382B」Sequential Nim
    「二分图」学习笔记
    题解 P3321 【[SDOI2015]序列统计】
    题解 P5339 【[TJOI2019]唱、跳、rap和篮球】
    题解 P3200 【[HNOI2009]有趣的数列】
    题解 P2606 【[ZJOI2010]排列计数】
    题解 CF1095F 【Make It Connected】
    题解 CF1155E 【Guess the Root】
  • 原文地址:https://www.cnblogs.com/SmilingEye/p/11757192.html
Copyright © 2020-2023  润新知