廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5087字,纯文字阅读大概需要8分钟。
内容图文
Java语言内置多线程支持:
- 创建线程需要操作系统资源(线程资源,栈空间)
- 频繁创建和销毁线程需要消耗大量时间
如果可以复用一个线程
线程池:
- 线程池维护若干个线程,处于等待状态
- 如果有新任务,就分配一个空闲线程执行
- 如果所有线程都处于忙碌状态,新任务放入队列等待
ExecutorService
JDK提供了ExecutorService接口表示线程池:
ExecutorService executor = Executors.newFixedThreadPool(4); //固定大小的线程池
executor.submit(task1); //提交任务到线程池
executor.submit(task2);
executor.submit(task3)
常用的ExecutorService:
- FixedThreadPool:线程数固定
- CachedThreadPool:线程数根据任务动态调整
- SingleThreadExecutor:仅单线程执行
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class PrintTask implements Runnable{
String name;
public PrintTask(String name){
this.name = name;
}
public void run(){
for(int i=0;i<3;i++){
System.out.println(i+" Hello,"+name+"!");
try{
Thread.sleep(1000);
}catch (InterruptedException e){}
}
}
}
public class ThreadPool {
public static void main(String[] args) throws InterruptedException{
ExecutorService executor = Executors.newFixedThreadPool(3); //指定线程数为3
executor.submit(new PrintTask("Bob"));
executor.submit(new PrintTask("Alice"));
executor.submit(new PrintTask("Tim"));
executor.submit(new PrintTask("Robot"));
Thread.sleep(10000);
executor.shutdown(); //结束线程池
}
}
//单个线程
ExecutorService executor = Executors.newSingleThreadExecutor();
//动态调整的线程池
ExecutorService executor = Executors.newCachedThreadPool();
查看newCachedThreadPool源码,发现其实现的是ThreadPoolExecutor的构造方法,
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, //初始化线程池的大小
Integer.MAX_VALUE,//线程池的最大值
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
//设置最大数量为10的动态线程池
ExecutorService executor = new ThreadPoolExecutor(0, 10,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
ScheduledThreadPool:一个任务可以定期反复执行
执行模式:
- Fixed Rate:固定的间隔,任务就会执行。例如每隔3秒任务就会启动,而不管这个任务执行多长、是否结束
- Fixed Delay:当任务执行完毕以后,等待1秒钟再继续执行。无论任务执行多久,只有在任务结束以后,等待1秒钟才会开始执行下一次的任务。
注意:ScheduledExecutorService不会自动停止
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);
executor.scheduleWithFixedDelay(new HelloTask("Alice"),2,5,TimeUnit.SECONDS);
}
}
Bob的执行频率比Alice高的多,任务开始的时间差也越来越大
问题:
1.FixedRate模式下,如果任务执行时间过长,后续任务会不会并发执行?
不会
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.如果任务抛出了异常,后续任务是否继续执行?
不会
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);
}
}
java.util.Timer 也可以定期执行任务
- 一个Timer对应一个Thread,只能定期执行一个任务。如果要执行多个定时任务,就必须要启动多个Timer。
- 必须在主线程结束时跳用Timer.cancel()
而一个ScheduledPool就可以调度多个任务,所以完全可以用新的Scheduled取代Timer类。
总结:
- JDK提供了ExecutorService实现了线程池功能
- 线程池内部维护一组线程,可以搞笑执行大量小任务
- Executors提供了静态方法创建不同类型的ExecutorService
- 必须调用shutdown()关闭ExecutorService
- ScheduledThreadPool可以定期调度多个任务
内容总结
以上是互联网集市为您收集整理的廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService全部内容,希望文章能够帮你解决廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。