Java并发编程——线程池的使用(三)线程池执行任务、取消任务
来源:互联网 发布:淘宝api接口开发教程 编辑:程序博客网 时间:2024/05/22 15:23
一、线程池执行Runnable任务
executor.execute(runnable)
executor.execute(new Runnable() { @Override public void run() { System.out.println("执行任务"); } });
log:
12-25 11:13:00.260 8710-8860/lbx.myapplication I/System.out: 执行任务
二、线程池取消任务,shutdown和shutdownNow
线程池取消任务的方法有两种:shutDown()方法和shutDownNow()方法。
2.1 shutdown的使用
先看段代码,栗子1:
public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new MyThread(), new ThreadPoolExecutor.AbortPolicy()); executor.execute(new Runnable() { @Override public void run() { System.out.println("执行任务"); } }); //调用shutdown方法 executor.shutdown(); //再次添加任务 executor.execute(new Runnable() { @Override public void run() { System.out.println("执行任务2"); } }); }
log:
12-25 14:35:20.810 6807-7022/lbx.myapplication I/System.out: 执行任务Caused by: java.util.concurrent.RejectedExecutionException······
log里抛出了异常:RejectedExecutionException,因为我们的拒绝策略是ThreadPoolExecutor.AbortPolicy,线程池shutdown后就不可以再添加新任务了。
这里大家可以再用不同的拒绝策略,自己打印log自己试一下,篇幅有限,我就不在这里一个一个试了。
栗子2:
public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new MyThread(), new ThreadPoolExecutor.AbortPolicy()); for (int i = 0; i < 10; i++) { final int finalI = i; executor.execute(new Runnable() { @Override public void run() { try { System.out.println("第" + finalI); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }); } try { Thread.sleep(300); //在主线程调用shutdown executor.shutdown(); System.out.println("已经shutdown了"); } catch (InterruptedException e) { e.printStackTrace(); } }
log:
12-25 15:02:19.130 11997-12132/lbx.myapplication I/System.out: 第012-25 15:02:19.130 11997-12134/lbx.myapplication I/System.out: 第212-25 15:02:19.130 11997-12133/lbx.myapplication I/System.out: 第112-25 15:02:19.130 11997-12135/lbx.myapplication I/System.out: 第312-25 15:02:19.130 11997-12136/lbx.myapplication I/System.out: 第412-25 15:02:19.430 11997-11997/lbx.myapplication I/System.out: 已经shutdown了12-25 15:02:19.630 11997-12132/lbx.myapplication I/System.out: 第512-25 15:02:19.630 11997-12134/lbx.myapplication I/System.out: 第612-25 15:02:19.630 11997-12133/lbx.myapplication I/System.out: 第712-25 15:02:19.630 11997-12135/lbx.myapplication I/System.out: 第812-25 15:02:19.630 11997-12136/lbx.myapplication I/System.out: 第9
跟之前的栗子1做对比我们发现,调用shutdown只是拒绝向队列里添加任务,而已经在队列里的任务,扔会继续执行。
2.2 shutdownNow的使用
栗子3:
继续用栗子1的代码就好,不同的是,把shutdown改成shutdownNow,其他地方不变,所以我就不上代码了,log也是一样的,仍然执行第一个任务,然后抛出异常RejectedExecutionException。
栗子4:同样的,继续用栗子2的代码就好,不同的是,把shutdown改成shutdownNow,其他地方不变,执行代码,看log:
12-25 15:30:57.560 2251-2424/lbx.myapplication I/System.out: 第012-25 15:30:57.560 2251-2425/lbx.myapplication I/System.out: 第112-25 15:30:57.560 2251-2426/lbx.myapplication I/System.out: 第212-25 15:30:57.560 2251-2428/lbx.myapplication I/System.out: 第412-25 15:30:57.570 2251-2427/lbx.myapplication I/System.out: 第312-25 15:30:57.860 2251-2251/lbx.myapplication I/System.out: 已经shutdownNow了
我们发现,调用shutdownNow后,这时线程池所执行的任务停止了,当然,新添加任务也是会被拒绝的,所以,shutdownNow会立刻停止所有正在执行的任务,并且队列不接受新的任务。
阅读全文