1) newScheduledThreadPool
newScheduledThreadPool-任务调度线程池是指,增加任务延时执行/定时执行功能的线程池。
在【任务调度线程池】功能加入之前,可以使用java.util.Timer来实现定时功能,Timer的优点在于简单易用,但由于所有任务都是同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都会影响到后面的任务。
相比于Timer,ScheduledThreadPool可以做到多线程执行任务,不会出现单线程串行执行任务的情况,而且前一任务出现异常,也不会影响后续任务。
ScheduledThreadPool提交task的方式为:pool.scheduler(Runnable/Callable对象,延时时间-delay,延时单位-TimeUnit)
延时执行线程任务:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TestScheduledPool {
public static void main(String[] args) {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
pool.schedule(()->{
System.out.println("fuckxueshu");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
},1,TimeUnit.SECONDS);
pool.schedule(()->{
System.out.println("fuckxueshu");
},1,TimeUnit.SECONDS);
}
}
定时执行线程任务:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TestScheduledPool {
public static void main(String[] args) {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
System.out.println("start...");
pool.scheduleAtFixedRate(()->{
System.out.println("running");
},1,1,TimeUnit.SECONDS);
}
}
pool.scheduleAtFixedRate()方法,间隔固定时间来执行一次任务,上例代码效果是初始延迟1秒,每隔1秒执行一次任务。
2) 正确处理线程池异常
当任务提交给线程池后,如果执行任务中存在异常,线程池默认既不会抛出异常也不会将控制信息显示,这由线程池的内部实现决定。
如果希望线程池能够处理任务中的异常,可以通过两种方式实现(适用于所有线程池):
1、任务本身捕获异常
try-catch块将异常语句包裹,出现异常则由catch块捕捉。
public class TestScheduledPool {
public static void main(String[] args) {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
pool.scheduleAtFixedRate(()->{
System.out.println("running");
try {
int i=1/0;
}catch (Exception e){
e.printStackTrace();
}
},1,1,TimeUnit.SECONDS);
}
2、以Future对象的形式返回任务结果
线程池使用submit等方法向线程池提交任务时,任务是存在返回值的,并使用Future对象接收返回值。通过这种方式实现的任务,如果任务中出现异常,当通过Future类的get方法获取结果时,控制台会报告错误信息,因为任务出现异常,无法返回值。
import java.util.concurrent.*;
public class TestScheduledPool {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
Future<Boolean> future = pool.submit(()->{
System.out.println("running");
int i=1/0;
return true;
});
future.get();
}
}
主线程执行到 future.get() 方法时,由于获取不到线程池返回的任务结果,会报以下错误: