());
```
3. ScheduledThreadPool
JDK还提供了ScheduledThreadPool,使一个任务可以定期反复执行。
执行模式:
Fixed Rate:在固定的间隔,任务就会执行。例如每隔3秒任务就会启动,而不管这个任务已执行了多长时间、是否结束
Fixed Delay:当任务执行完毕以后,等待1秒钟再继续执行。无论任务执行多久,只有在任务结束以后,等待1秒钟才会开始执行下一次的任务。
注意:ScheduledThreadPool不会自动停止,需要手动强制结束。
3.1示例
import java.time.LocalTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class HelloTask implements Runnable{
String name;
public HelloTask(String name){
this.name = name;
}
public void run(){
System.out.println("Hello,"+name+" ! It is "+LocalTime.now());
try{
Thread.sleep(1000);
}catch (InterruptedException e){}
System.out.println("Goodbye, "+name+"! It is "+LocalTime.now());
}
}
public class SchedulePool {
public static void main(String[] args) throws Exception{
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
executor.scheduleAtFixedRate(new HelloTask("Bob"),2,5,TimeUnit.SECONDS); //2秒以后开始执行,每5秒就执行这个任务
executor.scheduleWithFixedDelay(new HelloTask("Alice"),2,5,TimeUnit.SECONDS); //2秒以后开始执行,执行结束等待5秒再执行
}
}
Bob的执行频率比Alice高的多,任务开始的时间差也越来越大
问题:
1.FixedRate模式下,如果任务执行时间过长,后续任务会不会并发执行?
不会
```#java
import java.time.LocalTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class HelloTask implements Runnable{
String name;
public HelloTask(String name){
this.name = name;
}
public void run(){
System.out.println("Hello,"+name+" ! It is "+LocalTime.now());
try{
Thread.sleep(10000);
}catch (InterruptedException e){}
System.out.println("Goodbye, "+name+"! It is "+LocalTime.now());
}
}
public class SchedulePool {
public static void main(String[] args) throws Exception{
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
executor.scheduleAtFixedRate(new HelloTask("Bob"),2,1,TimeUnit.SECONDS);
}
}
2.如果任务抛出了异常,后续任务是否继续执行?
不会
```#java
import java.time.LocalTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class HelloTask implements Runnable{
String name;
int count;
public HelloTask(String name,int count){
this.name = name;
this.count = count;
}
public void run(){
System.out.println("Hello,"+name+" ! It is "+LocalTime.now()+" "+count);
try{
if(count == 3){
throw new RuntimeException("我是故意的");
}
Thread.sleep(1000);
}catch (InterruptedException e){}
System.out.println("Goodbye, "+name+"! It is "+LocalTime.now());
count++;
}
}
public class SchedulePool {
public static void main(String[] args) throws Exception{
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
executor.scheduleAtFixedRate(new HelloTask("Bob",0),2,5,TimeUnit.SECONDS);
}
}
4. java.util.Timer
jdk还提供了java.util.Timer类,这个类也可以定期执行一个任务:
一个Timer对应一个Thread,只能定期执行一个任务。如果要执行多个定时任务,就必须要启动多个Timer。
必须在主线程结束时跳用Timer.cancel()
而一个ScheduledPool就可以调度多个任务,所以完全可以用新的Scheduled取代Timer类。
5. 总结:
JDK提供了ExecutorService实现了线程池功能
线程池内部维护一组线程,可以搞笑执行大量小任务
Executors提供了静态方法创建不同类型的ExecutorService
必须调用shutdown()关闭ExecutorService
ScheduledThreadPool可以定期调度多个任务