1、什么是线程池
Java当中,为了规避频繁创建调度进程的开销,我们引入了线程。但是如果进一步提高创建销毁频率,线程的开销也不容忽视。
对此我们有两个解决方案
· 协程(轻量级线程):相比线程,把系统调度的过程省略了。
· 线程池:在使用第一个线程的时候,提前把其余线程创建好。后续如果想使用新的线程,不必重新创建,可以直接用。
(使用池中的线程比创建线程更高效的原因是:创建线程涉及到内核态操作(操作系统内核会给所有线程提供服务),过程是不可控的)
在Java当中,我们更常用的是线程池方案
线程池的优点有
降低资源消耗,复用已创建的线程来降低创建和销毁线程的消耗。
提高响应速度,任务到达时,可以不需要等待线程的创建立即执行。
提高线程的可管理性,使用线程池能够统一的分配、调优和监控。
2、创建线程池的方法
(1)newCachedThreadPool()方法
我们把newCachedThreadPool()和下面提到的几种方法称之为工厂方法,对象并不是调用new来实现的
ExecutorService service = Executors.newCachedThreadPool();
newCachedThreadPool()创建线程池的线程数目是可以动态适应的。随着往线程池里添加任务,线程会被自动创建出来;任务执行完后,线程也不会立刻销毁,而是保留一段时间,方便后续调用
(2) newFixedThreadPool()方法
ExecutorService service = Executors.newFixedThreadPool(4);
newFixedThreadPool()方法创建的线程数量是固定的,上面代码中的4就是线程数
(3)newSingleThreadExecutor()方法
ExecutorService service = Executors.newSingleThreadExecutor();
该方法只能创建单个线程
(4)newScheduledThreadPool()方法
ExecutorService service = Executors.newScheduledThreadPool(4);
该方法创建的线程池类似于定时器,由多个线程执行时间到了的任务
什么是定时器?
3、添加任务
在创建线程池后,我们就应该接着添加任务
添加任务所用的方法是submit()方法
service.submit(new Runnable() {
@Override
public void run() {
System.out.println("111");
}
});
submit()的参数即重写run方法的匿名内部类
在添加任务后,就可以直接运行程序啦!
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class demo1 {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
service.submit(new Runnable() {
@Override
public void run() {
System.out.println("111");
}
});
}
}
运行结果