线程池的概念
我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?
在Java中可以通过线程池来达到这样的效果:
(1)首先介绍在Tcp服务器编程模型的原理,每一个客户端连接用一个单独的线程为之服务,当与客户端的会话结束时,线程也就结束了,即每来一个客户端连接,服务器端就要创建一个新线程。
(2)程池首先创建一些线程,它们的集合称为线程池,当服务器接受到一个客户请求后,就从线程池中取出一个空闲的线程为之服务,服务完后不关闭该线程,而是将该线程还回到线程池中。
(3)任务是提交给整个线程池,一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务,池中的线程会各自同时执行一个任务,其他任务会排队等待
(4)所有任务执行完后线程还存在,程序不会结束,需要手动关闭线程池
(5)不需要和传统方式一样把任务交给特定的线程执行,而是把任务交给线程池,如果池中有空闲线程,就执行该任务,否则任务就等待被执行
优点:
合理利用线程池能够带来三个好处。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。但是要做到合理的利用线程池,必须对其原理了如指掌。
Executors类的简单应用
1.创建固定大小的线程池
2.创建缓存线程池//线程数可随需求变化
3.创建单一线程池(实现线程死掉之后重新启动)
package cn.itcast.heima;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadPool {
public static void main(String[] args) {
//创建一个固定大小的线程池,里面有3个线程
ExecutorService threadPool = Executors.newFixedThreadPool(3);
//创建一个缓存的线程池,池中线程不够,会自动创建新的线程
//ExecutorService threadPool = Executors.newCachedThreadPool();
//创建单一线程池,好处是始终保证池中有一个线程存在,如果线程死了,会再创建一个
//ExecutorService threadPool = Executors.newSingleThreadExecutor();
//通过循环向池中添加10个任务,但是同时只有3个任务被池中的3个线程执行,只有这3个任务都执行结束了才会执行其余任务
for(int i=1;i<=10;i++){
final int task = i;
threadPool.execute(new Runnable(){
public void run() {
//任务循环10遍,线程池中的某一个线程就会执行该任务
for(int j=1;j<=10;j++){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" is looping of "+j+" for task "+task);
}
}
});
}
System.out.println("all of 10 tasks has committed!");
threadPool.shutdown();//关闭线程池(当所有的任务执行完毕,所有的线程都空闲下来时,结束池中的所有线程)
//threadPool.shutdownNow();//关闭线程池(立即结束池中的所有线程,即使还有任务没有执行完毕)
//创建一个调度线程池
Executors.newScheduledThreadPool(3).schedule(
new Runnable(){
public void run() {
System.out.println("bombing!");
}
},
3,//delay
TimeUnit.SECONDS);
}
}
大佬的详解线程池,拜读~ https://www.cnblogs.com/dolphin0520/p/3932921.html