java多线程----拒绝策略
本章介绍线程池的拒绝策略。内容包括:
转载请注明出处:
拒绝策略介绍
线程池的拒绝策略,是指当任务添加到线程池中被拒绝,⽽采取的处理措施。
当任务添加到线程池中之所以被拒绝,可能是由于:第⼀,线程池异常关闭。第⼆,任务数量超过线程池的最⼤限制。线程池共包括4种拒绝策略,它们分别是:AbortPolicy, CallerRunsPolicy, DiscardOldestPolicy和DiscardPolicy。AbortPolicy -- 当任务添加到线程池中被拒绝时,它将抛出 RejectedExecutionException 异常。
CallerRunsPolicy -- 当任务添加到线程池中被拒绝时,会在线程池当前正在运⾏的Thread线程池中处理被拒绝的任务。DiscardOldestPolicy -- 当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。DiscardPolicy -- 当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务。
线程池默认的处理策略是AbortPolicy!
拒绝策略对⽐和⽰例
下⾯通过⽰例,分别演⽰线程池的4种拒绝策略。
1. DiscardPolicy ⽰例
1 import flect.Field;
2 import urrent.ArrayBlockingQueue;
3 import urrent.ThreadPoolExecutor;
4 import urrent.TimeUnit;
通天门
5 import urrent.ThreadPoolExecutor.DiscardPolicy;
6
7 public class DiscardPolicyDemo {
8
9 private static final int THREADS_SIZE = 1;
10 private static final int CAPACITY = 1;
11
12 public static void main(String[] args) throws Exception {
13
14 // 创建线程池。线程池的"最⼤池⼤⼩"和"核⼼池⼤⼩"都为1(THREADS_SIZE),"线程池"的阻塞队列容量为1(CAPACITY)。
15 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS,
16 new ArrayBlockingQueue<Runnable>(CAPACITY));
17 // 设置线程池的拒绝策略为"丢弃"
18 pool.tRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
19
20 // 新建10个任务,并将它们添加到线程池中。
21 for (int i = 0; i < 10; i++) {
22 Runnable myrun = new MyRunnable("task-"+i);
23 ute(myrun);
蜜蜂简介24 }
25 // 关闭线程池
26 pool.shutdown();
27 }
28 }
29
30 class MyRunnable implements Runnable {
31 private String name;
32 public MyRunnable(String name) {
33 this.name = name;
34 }
35 @Override
36 public void run() {
37 try {
38 System.out.println(this.name + " is running.");
39 Thread.sleep(100);
40 } catch (Exception e) {
英雄联盟隐藏分
41 e.printStackTrace();
42 }
43 }
44 }
运⾏结果:
task-0 is running.
task-1 is running.
结果说明:线程池pool的"最⼤池⼤⼩"和"核⼼池⼤⼩"都为1(THREADS_SIZE),这意味着"线程池能同时运⾏的任务数量最⼤只能是1"。
线程池pool的阻塞队列是,ArrayBlockingQueue是⼀个有界的阻塞队列,ArrayBlockingQueue的容量为1。这也意味着线程池的阻塞队列只能有⼀个线程池阻塞等待。
根据""中分析的execute()代码可知:线程池中共运⾏了2个任务。第1个任务直接放到Worker中,通过
线程去执⾏;第2个任务放到阻塞队列中等待。其他的任务都被丢弃了!
2. DiscardOldestPolicy ⽰例
1 import flect.Field;
2 import urrent.ArrayBlockingQueue;
3 import urrent.ThreadPoolExecutor;
4 import urrent.TimeUnit;
5 import urrent.ThreadPoolExecutor.DiscardOldestPolicy;
6
7 public class DiscardOldestPolicyDemo {
8qq斗地主电脑版
9 private static final int THREADS_SIZE = 1;
10 private static final int CAPACITY = 1;
11
12 public static void main(String[] args) throws Exception {
13
14 // 创建线程池。线程池的"最⼤池⼤⼩"和"核⼼池⼤⼩"都为1(THREADS_SIZE),"线程池"的阻塞队列容量为1(CAPACITY)。
15 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS,
16 new ArrayBlockingQueue<Runnable>(CAPACITY));
17 // 设置线程池的拒绝策略为"DiscardOldestPolicy"
18 pool.tRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
19
20 // 新建10个任务,并将它们添加到线程池中。
21 for (int i = 0; i < 10; i++) {
22 Runnable myrun = new MyRunnable("task-"+i);
23 ute(myrun);
24 }
25 // 关闭线程池
26 pool.shutdown();
荷兰阵容
27 }
28 }
29
30 class MyRunnable implements Runnable {
31 private String name;
32 public MyRunnable(String name) {
33 this.name = name;
34 }
35 @Override
36 public void run() {
37 try {
38 System.out.println(this.name + " is running.");
39 Thread.sleep(200);
40 } catch (Exception e) {
41 e.printStackTrace();
42 }
43 }
44 }
运⾏结果:
task-0 is running.
task-9 is running.
结果说明:将"线程池的拒绝策略"由DiscardPolicy修改为DiscardOldestPolicy之后,当有任务添加到线程池被拒绝时,线程池会丢弃阻塞队列中末尾的任务,然后将被拒绝的任务添加到末尾。
3. AbortPolicy ⽰例
1 import flect.Field;
2 import urrent.ArrayBlockingQueue;
3 import urrent.ThreadPoolExecutor;
4 import urrent.TimeUnit;
5 import urrent.ThreadPoolExecutor.AbortPolicy;
6 import urrent.RejectedExecutionException;
7
8 public class AbortPolicyDemo {
9
10 private static final int THREADS_SIZE = 1;
11 private static final int CAPACITY = 1;
12
13 public static void main(String[] args) throws Exception {
14
15 // 创建线程池。线程池的"最⼤池⼤⼩"和"核⼼池⼤⼩"都为1(THREADS_SIZE),"线程池"的阻塞队列容量为1(CAPACITY)。
16 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS,
17 new ArrayBlockingQueue<Runnable>(CAPACITY));
18 // 设置线程池的拒绝策略为"抛出异常"
19 pool.tRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
20
21 try {
22
23 // 新建10个任务,并将它们添加到线程池中。
24 for (int i = 0; i < 10; i++) {
25 Runnable myrun = new MyRunnable("task-"+i);
26 ute(myrun);
27 }
28 } catch (RejectedExecutionException e) {
29 e.printStackTrace();
30 // 关闭线程池
31 pool.shutdown();
32 }
33 }
34 }
35
36 class MyRunnable implements Runnable {
37 private String name;
38 public MyRunnable(String name) {
39 this.name = name;
40 }
41 @Override
42 public void run() {
43 try {
44 System.out.println(this.name + " is running.");
45 Thread.sleep(200);
46 } catch (Exception e) {
47 e.printStackTrace();
48 }
49 }
50 }
(某⼀次)运⾏结果:
urrent.RejectedExecutionException
at urrent.jectedExecution(ThreadPoolExecutor.java:1774)
at ject(ThreadPoolExecutor.java:768)
at ute(ThreadPoolExecutor.java:656)
at AbortPolicyDemo.main(AbortPolicyDemo.java:27)
task-0 is running.
task-1 is running.
结果说明:将"线程池的拒绝策略"由DiscardPolicy修改为AbortPolicy之后,当有任务添加到线程池被拒绝时,会抛出RejectedExecutionException。
4. CallerRunsPolicy ⽰例
1 import flect.Field;
2 import urrent.ArrayBlockingQueue;
3 import urrent.ThreadPoolExecutor;
4 import urrent.TimeUnit;
5 import urrent.ThreadPoolExecutor.CallerRunsPolicy;
6
7 public class CallerRunsPolicyDemo {
8
9 private static final int THREADS_SIZE = 1;
10 private static final int CAPACITY = 1;
11
12 public static void main(String[] args) throws Exception {
13
菜摊14 // 创建线程池。线程池的"最⼤池⼤⼩"和"核⼼池⼤⼩"都为1(THREADS_SIZE),"线程池"的阻塞队列容量为1(CAPACITY)。
15 ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS,
16 new ArrayBlockingQueue<Runnable>(CAPACITY));
17 // 设置线程池的拒绝策略为"CallerRunsPolicy"
18 pool.tRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());徽州府衙
19
20 // 新建10个任务,并将它们添加到线程池中。
21 for (int i = 0; i < 10; i++) {
雪燕的食用方法22 Runnable myrun = new MyRunnable("task-"+i);
23 ute(myrun);
24 }
25
26 // 关闭线程池
27 pool.shutdown();
28 }
29 }
30
31 class MyRunnable implements Runnable {
32 private String name;
33 public MyRunnable(String name) {
34 this.name = name;
35 }
36 @Override
37 public void run() {
38 try {
39 System.out.println(this.name + " is running.");
40 Thread.sleep(100);
41 } catch (Exception e) {
42 e.printStackTrace();
43 }
44 }
45 }
(某⼀次)运⾏结果:
task-2 is running.
task-3 is running.
task-4 is running.
task-5 is running.
task-6 is running.
task-7 is running.
task-8 is running.
task-9 is running.
task-0 is running.
task-1 is running.
结果说明:将"线程池的拒绝策略"由DiscardPolicy修改为CallerRunsPolicy之后,当有任务添加到线程池被拒绝时,线程池会将被拒绝的任务添加到"线程池正在运⾏的线程"中取运⾏。