1,线程池的作用
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果。
2,为什么要用线程池?
(1).减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
(2).可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存
3,比较重要的几个类和描述
ExecutorService 真正的线程池接口。
ScheduledExecutorService 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。
ThreadPoolExecutor ExecutorService的默认实现。
ScheduledThreadPoolExecutor 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。
4,new Thread的弊端
(1).每次new Thread新建对象性能差。
(2).线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
(3).缺乏更多功能,如定时执行、定期执行、线程中断。
相比new Thread,Java提供的四种线程池的好处在于:
(1).重用存在的线程,减少对象创建、消亡的开销,性能佳。
(2).可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
(3).提供定时执行、定期执行、单线程、并发数控制等功能。
5,四种线程池
Java通过Executors提供四种线程池,分别为:
1,newCachedThreadPoo
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2,newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3,newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
4,newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
6,创建四种线程池 示例
(1),newCachedThreadPool
创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程, 那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。
1 package io.ymq.thread.demo1; 2 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 6 /** 7 * 描述: 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。 8 * 此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。 9 * 10 * @author yanpenglei 11 * @create 2017-10-12 11:13 12 **/ 13 public class TestNewCachedThreadPool { 14 public static void main(String[] args) { 15 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); 16 for (int i = 1; i <= 10; i++) { 17 final int index = i; 18 try { 19 Thread.sleep(index * 1000); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 24 cachedThreadPool.execute(new Runnable() { 25 26 @Override 27 public void run() { 28 String threadName = Thread.currentThread().getName(); 29 System.out.println("执行:" + index + ",线程名称:" + threadName); 30 } 31 }); 32 } 33 } 34 }
(2),newFixedThreadPool
描述:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。
线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
package io.ymq.thread.demo2; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 描述:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。 * 线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。 * * @author yanpenglei * @create 2017-10-12 11:30 **/ public class TestNewFixedThreadPool { public static void main(String[] args) { ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); for (int i = 1; i <= 10; i++) { final int index = i; fixedThreadPool.execute(new Runnable() { @Override public void run() { try { String threadName = Thread.currentThread().getName(); System.out.println("执行:" + index + ",线程名称:" + threadName); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
(3),newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行
package io.ymq.thread.demo3; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 描述:创建一个定长线程池,支持定时及周期性任务执行。延迟执行 * * @author yanpenglei * @create 2017-10-12 11:53 **/ public class TestNewScheduledThreadPool { public static void main(String[] args) { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); scheduledThreadPool.schedule(new Runnable() { @Override public void run() { System.out.println("表示延迟3秒执行。"); } }, 3, TimeUnit.SECONDS); scheduledThreadPool.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("表示延迟1秒后每3秒执行一次。"); } }, 1, 3, TimeUnit.SECONDS); } }
(4),newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
package io.ymq.thread.demo4; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 描述:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 * * @author yanpenglei * @create 2017-10-12 12:05 **/ public class TestNewSingleThreadExecutor { public static void main(String[] args) { ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); for (int i = 1; i <= 10; i++) { final int index = i; singleThreadExecutor.execute(new Runnable() { @Override public void run() { try { String threadName = Thread.currentThread().getName(); System.out.println("执行:" + index + ",线程名称:" + threadName); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
https://blog.csdn.net/achuo/article/details/80623893/
标签:Java,Executors,创建,任务,线程,执行,public,四种 From: https://www.cnblogs.com/zhaosq/p/14435812.html