对于每次创建线程--关闭线程的过程都是一个耗费性能的过程。在处理大型业务时,每进行一个任务就要创建一个线程,任务完是十分浪费计算机性能的。这时我们就可以借助线程池这个媒介来处理多个任务。线程池是存放线程的,当任务需要用到线程时,先看线程池里是否有空闲线程,若有空闲的就可以直接用,若没有空闲的需要在线程池中再创建新的线程,并且这个新的线程在使用完后仍存在线程池中,留待其他任务使用。
使用线程池的优点:
1、重用线程池的线程,避免因为线程的创建和销毁锁带来的性能开销
2、有效控制线程池的最大并发数,避免大量的线程之间因抢占系统资源而阻塞
3、能够对线程进行简单的管理,并提供一下特定的操作如:可以提供定时、定期、单线程、并发数控制等功能。
一、创建线程池newCachedThreadPool
ExecutorService cachedThreadPool= Executors.newCachedThreadPool();
这是一个线程数量不定的线程池。最大线程数量为Integer.MAX_VALUE。
这个线程池中的线程在完成任务后会等待60s,如果没有任务让线程执行,这个线程会被回收。
案例:
将线程-1~线程-10输出三遍
public class 线程池newCachedThreadPool {
public static void main(String[] args){
ExecutorService cachedThreadPool= Executors.newCachedThreadPool();
for(int i=0;i<30;i++){
Tt t=new Tt();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(t);
}
}
}
class Tt implements Runnable{
@Override
public void run() {
//for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"正在执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//}
}
}
二、创建线程池newFixedThreadPool
ExecutorService service= Executors.newFixedThreadPool(5);
这个线程池可指定工作线程数量
创建这个线程池需要传一个整型参数,表示线程池中最大的线程数量
当线程池中正在工作的线程数已达到最大,并且来了新的任务时,新的任务须处在缓存队列中,等待分配线程资源。
这个线程池中的线程在完成任务后不会被回收,会一直处在一个待用状态。
案例:
public class 线程池newFixedThreadPool {
public static void main(String[] args){
ExecutorService service= Executors.newFixedThreadPool(5);
for(int i=0;i<10;i++){
Tr t=new Tr();
service.execute(t);
}
}
}
class Tr implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行完毕");
}
}
三、创建线程池newScheduledThreadPool
这个线程池的核心线程数量是固定的,非核心线程数是没有限制的,当非核心线程闲置时会被立即回收,他可安排给延迟运行命令或者定期地执行。
这类线程池主要用于执行定时任务和具有固定周期的重复任务。
四、创建线程池newSingleThreadExecutor
内部只有一个核心线程,以无界队列方式来执行该线程,这使得这些任务之间不需要处理线程同步的问题,他确保所有的任务都在同一个线程中按顺序中执行,并且可以在任意给定的时间不会有多个线程是活动的。
五、关闭线程池
1、cachedThreadPool.shutdown();//终止线程
线程池不会立即退出,直到添加到线程池中的任务都处理完才会退出。
2、cachedThreadPool.shutdownNow();//终止线程并返回未执行完毕的任务
线程池立刻退出,试图停止所有正在执行的任务,并不再处理正等待的任务 。