为什么需要线程池
- 线程的创建它会开辟本地方法栈、虚拟机栈、程序计数器等线程私有的内存,同时销毁的时候需要销毁以上3个区域,因此频繁的创建和消耗比较消耗系统资源;
- 当任务量远远大于线程可以处理的任务量的时候,并不能友好拒绝任务。
基于线程的以上两个缺点,为了解决这样的缺点,我们引入了线程池。
什么是线程池
就是使用池化技术来管理线程和使用线程的方式。类似于生活中的一个仓库,当我们需要某个工具的时候直接去仓库取就可以了,用完放回去,下次还能继续使用。而线程池就是放线程的一个“仓库”,需要的时候取,用完放回去,下次还能用,不需要在频繁的创建和销毁线程了。线程池中的任务队列可以很好地管理并执行任务。线程池是长生命周期的,启动后不会主动关闭。
线程池的优点
1.可以避免频繁的创建和消耗线程。
2.可以更好的管理线程的个数和资源的个数。
3.拥有更多的功能,比如线程池可以进行定时任务的执行。
4.线程池可以更友好的拒绝不能处理的任务。
线程池的创建方式
1、创建固定个数的线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建一个固定个数的线程池
ExecutorService executorService =
Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
// 执行任务
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程名:" +
Thread.currentThread().getName());
}
});
}
}
}
这种方式并不是一开始即初始化时就创建10个线程,而是根据你的任务量进行创建,假如你的任务两个线程就可以完成,他就只创建两个线程,当你的任务量加大的时候,这两个线程不够用了,才会在创建线程,但最多只能创建10个。
当然这种方式还可以自定义线程池规则(如线程池的名称、优先级…) :
public class ThreadPoolDemo {
public static void main(String[] args) {
// 自定义线程工厂
MyThreadFactory threadFactory = new MyThreadFactory();
ExecutorService executorService =
Executors.newFixedThreadPool(10, threadFactory);
for (int i = 0; i < 10; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
Thread thread = Thread.currentThread();
System.out.println("线程名:" +
thread.getName() +
",优先级:" + thread.getPriority());
}
});
}
}
private static int count = 1;
static class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
// 自定义线程池的名称规则
thread.setName