线程池
使用线程池有哪些优势
1:线程和任务分离,提升线程重用性;
2:控制线程并发数量,降低服务器压力,统一管理所有线程;
3:提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程池就免去了T1和T3的时间;(复用线程)
Runnable接口的弊端
Runnable新建线程,性能差
线程缺乏统一管理,可能无限制的新建线程,相互竞争,严重时会占用过多系统资源导致死机或内存溢出
ThreadPool线程池
重用存在的线程,减少线程对象创建、消亡的开销
线程总数可控,提高资源的利用率
提供额外功能,定时执行、定期执行、监控等
四种线程池
JUC支持的线程池种类
在java.util.concurrent中,提供了工具类Executors(调度 器)对象来创建线程池,可创建的线程池有四种:
1. FixedThreadPool-定长线程池
2. CachedThreadPool-可缓存线程池
3. SingleThreadExecutor-单线程池
4. ScheduledThreadPool-调度线程池
定长线程池( FixedThreadPool)
创建一个指定大小的线程池,可控制线程的最大并发数,超出的线程会在LinkedBlockingQueue阻塞队列中等待
importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; publicclassThreadPoolSample1 { publicstaticvoidmain(String[] args) { //创建一个可创建一个定长线程池//定长线程池的特点是固定线程总数,空闲线程用于执行任务,如果线程都在使用,后续任务则处于等待状态ExecutorServicees=Executors.newFixedThreadPool(10); for(inti=1; i<=50 ; i++){ finalintindex=i; //不需要返回值,使用execute方法执行Runnable对象//可以使用匿名类简化代码es.execute(newRunnable() { publicvoidrun() { System.out.println(Thread.currentThread().getName()+":"+index ); } }); /*需要返回值,使用submit方法执行Callable对象,利用Future对象接收返回值Future<Object> ret = es.submit(new Callable<Object>() {@Overridepublic Object call() throws Exception {return null;}});*/ } //处理完毕关闭线程池es.shutdown(); } }
可缓存线程池(CachedThreadPool)
创建一个可缓存的无界线程池,如果线程池长度超过处理需要,可灵活回收空线程,若无可回收,则新建线程。当线程池中的线程空闲时间超过60s,则会自动回收该线程,当任务超过线程池的线程数则创建新的线程,线程池的大小上限为Integer.MAX_VALUE,可看作无限大。
importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; /*演示*/publicclassThreadPoolSample2 { publicstaticvoidmain(String[] args) { //调度器对象//ExecutorService用于管理线程池ExecutorServicethreadPool=Executors.newCachedThreadPool();//创建一个可缓存线程池//可缓存线程池的特点是,无限大,如果线程池中没有可用的线程则创建,有空闲线程则利用起来for(inti=1 ; i<=1000 ; i++) { finalintindex=i; threadPool.execute(newRunnable() { publicvoidrun() { System.out.println(Thread.currentThread().getName() +":"+index); } }); } threadPool.shutdown(); } }
可缓存线程池(CachedThreadPool)
创建一个可缓存的无界线程池,如果线程池长度超过处理需要,可灵活回收空线程,若无可回收,则新建线程。当线程池中的线程空闲时间超过60s,则会自动回收该线程,当任务超过线程池的线程数则创建新的线程,线程池的大小上限为Integer.MAX_VALUE,可看作无限大。
importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; /*演示*/publicclassThreadPoolSample2 { publicstaticvoidmain(String[] args) { //调度器对象//ExecutorService用于管理线程池ExecutorServicethreadPool=Executors.newCachedThreadPool();//创建一个可缓存线程池//可缓存线程池的特点是,无限大,如果线程池中没有可用的线程则创建,有空闲线程则利用起来for(inti=1 ; i<=1000 ; i++) { finalintindex=i; threadPool.execute(newRunnable() { publicvoidrun() { System.out.println(Thread.currentThread().getName() +":"+index); } }); } threadPool.shutdown(); } }
单线程池(SingleThreadExecutor)
创建一个单线程化的线程池,它只有一个线程,用仅有的一个线程来执行任务,保证所有的任务按照指定顺序(FIFO,LIFO,优先级)执行,所有的任务都保存在队列LinkedBlockingQueue中,等待唯一的单线程来执行任务。
importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; publicclassThreadPoolSample3 { publicstaticvoidmain(String[] args) { //调度器对象//ExecutorService用于管理线程池ExecutorServicethreadPool=Executors.newSingleThreadExecutor();//单线程线程池for(inti=1 ; i<=1000 ; i++) { finalintindex=i; threadPool.execute(newRunnable() { publicvoidrun() { System.out.println(Thread.currentThread().getName() +":"+index); } }); } threadPool.shutdown(); } }
调度线程池(ScheduledThreadPool)
importjava.util.Date; importjava.util.concurrent.Executors; importjava.util.concurrent.ScheduledExecutorService; importjava.util.concurrent.TimeUnit; publicclassThreadPoolSample4 { publicstaticvoidmain(String[] args) { //调度线程池ScheduledExecutorServicescheduledThreadPool=Executors.newScheduledThreadPool(5);//可调度线程池//初始延迟1秒执行,每三秒执行一次scheduledThreadPool.scheduleAtFixedRate(newRunnable() { publicvoidrun() { System.out.println(newDate() +"延迟1秒执行,每三秒执行一次"); } }, 1, 3, TimeUnit.SECONDS); } }