线程池中使用FutureTask时候当拒绝策略为DiscardPolicy和 DiscardOldestPolicy的时候在被拒绝的任务的FutureTask对象上调用get()方法会导致调用线程一直阻塞,所以在日常开发中尽量使用带超时参数的get方法以避免线程一直阻塞,另外通过重写这些拒绝策略设置拒绝任务的状态也可以达到想要的效果。多线程下使用时候最好使用ThreadLocal对象

设置超时时间和设置FutureTask任务状态为结束状态即可

引用自: https://www.jianshu.com/p/a9f4f4478a00

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package book.base.thread;

import java.util.concurrent.*;


public class FutureTaskTestDemo {


private static RejectedExecutionHandler futureTaskRejectPolicy= new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if(!executor.isShutdown()){
if(r!=null && r instanceof FutureTask){
((FutureTask) r).cancel(true);
}
}
}
};

private static RejectedExecutionHandler defaultPolicy=new ThreadPoolExecutor.AbortPolicy(){
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
System.out.println("发生了丢弃" + r.getClass());
super.rejectedExecution(r,e);
}
};

public static void main(String[] args) throws Exception{

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1),futureTaskRejectPolicy);
Future<String> firstFuture=threadPoolExecutor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("first开始睡眠");
Thread.sleep(10000);
System.out.println("first睡醒了");
return "first one";
}
});

Future<String> secondFuture=threadPoolExecutor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("second开始睡眠");
// Thread.sleep(5000);
System.out.println("second睡醒了");
return "second one";
}
});


Future<String> thirdFuture=null;
try {
thirdFuture=threadPoolExecutor.submit(new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("third开始睡眠");
// Thread.sleep(5000);
System.out.println("third睡醒了");
return "third one";
}
});

}catch (Exception ex){
ex.printStackTrace();
}

System.out.println("first one 结果:"+ firstFuture.get());
System.out.println("second one 结果:"+ secondFuture.get());
try{
System.out.println("third one 结果:"+ (thirdFuture==null?null:thirdFuture.get()));
}catch (Exception ex){
ex.printStackTrace();
}

threadPoolExecutor.shutdown();





}
}

输出:

1
2
3
4
5
6
7
8
9
10
first开始睡眠
first睡醒了
first one 结果:first one
second开始睡眠
second睡醒了
second one 结果:second one
java.util.concurrent.CancellationException
at java.util.concurrent.FutureTask.report(FutureTask.java:121)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at book.base.thread.FutureTaskTestDemo.main(FutureTaskTestDemo.java:73)