package com.middle.threadpool;
import java.util.concurrent.*;
/**
* @author 15510
* @create 2019-07-31 20:39
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0; i < 5; i++) {
int index = i;
executorService.submit(() -> divTask(100, index));
}
executorService.shutdown();
}
private static void divTask(int a, int b) {
double result = a / b;
System.out.println(result);
}
}
结果如下
100.0
33.0
50.0
25.0
Process finished with exit code 0
上述代码,可以看出运行结果为4个,应该是有5个的,但是当 i=0 的时候,100/0是会报错的,但是日志信息中没有任何信息,是为什么那?如果使用了 submit(Runnable task) 就会出现这种情况,任何的错误信息都出现不了!
这是因为使用 submit(Runnable task) 的时候,错误的堆栈信息跑出来的时候会被内部捕获到,所以打印不出来具体的信息让我们查看,解决的方法有如下两种:
- 使用 execute() 代替 submit()
package com.middle.threadpool;
import java.util.concurrent.*;
/**
* @author 15510
* @create 2019-07-31 20:39
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0; i < 5; i++) {
int index = i;
executorService.execute(() -> divTask(100, index));
}
executorService.shutdown();
}
private static void divTask(int a, int b) {
double result = a / b;
System.out.println(result);
}
}
结果
Exception in thread "pool-1-thread-1" 100.0
25.0
33.0
50.0
java.lang.ArithmeticException: / by zero
at com.middle.threadpool.ThreadPoolDemo.divTask(ThreadPoolDemo.java:22)
at com.middle.threadpool.ThreadPoolDemo.lambda$main$0(ThreadPoolDemo.java:16)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Process finished with exit code 0
- 使用Future
package com.middle.threadpool;
import java.util.concurrent.*;
/**
* @author 15510
* @create 2019-07-31 20:39
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0; i < 5; i++) {
int index = i;
Future<?> future = executorService.submit(() -> divTask(100, index));
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
executorService.shutdown();
}
private static void divTask(int a, int b) {
double result = a / b;
System.out.println(result);
}
}
结果
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.middle.threadpool.ThreadPoolDemo.main(ThreadPoolDemo.java:19)
Caused by: java.lang.ArithmeticException: / by zero
at com.middle.threadpool.ThreadPoolDemo.divTask(ThreadPoolDemo.java:28)
at com.middle.threadpool.ThreadPoolDemo.lambda$main$0(ThreadPoolDemo.java:16)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
100.0
50.0
33.0
25.0
Process finished with exit code 0
- execute 和 submit 的区别
execute() 方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。
submit() 方法用于提交需要返回值的任务。线程池会返回一个 future 类型的对象,通过这个 future 对象可以判断任务是否执行成功,并且可以通过 future 的 get() 方法来获取返回值,get() 方法会阻塞当前线程直到任务完成,而使用 get(long timeout,TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。
没有返回值也是可以用submit