线程池的作用:
就是限制在系统中可以执行的线程的数量。根据系统环境的情况,自动或手动设置线程数量,以达到运行的最佳效果。
用线程池控制线程的数量,多余的线程必须排队等候,一个任务执行完毕,再从队列中取最前面的任务开始执行。如果队列中没有等待的线程,线程池的资源就处于等待的状态。当一个新任务需要运行时,如果线程池中有等待的工作线程,就歌词开始运行,否则进入等待队列。
为什么需要使用线程池
-
减少创建和销毁线程的次数,每个工作线程都可以被重复复用,可执行多个任务。
-
可以根据系统的随能力,调整线程池中工作线程的数量,防止因为消耗过多的内存,导致服务器崩溃。
Java里面线程池顶级接口是Executor,但是从严格意义上来讲Executor并不是一个线池,只是一个执行线程的工具。
比较重要的几个类:
ExecutorService:真正的线程池接口
ScheduleExecutorService:解决那些需要任务重复执行的问题
ThreadPoolExecutor:ExecutorSrevice的默认实现
ScheduleThreadPoolExecutor:继承ThreadPoolExecutor的ScheduledExecutorService接口的实现,周期性任务调试的类实现。
Executors类里提供了一些静态工厂,生成一些常用的线程池。
方法 | 解释 |
---|---|
newCachedThreadPool(ThreadPoolExecutor) | 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,就会回收部分空闲的线程(60秒没有执行的线程),当任务数量增加时,以可以智能的添加新的线程来处理任务。这个线程池不会对线程池的大小进行限制,线程池的大小完全依赖操作系统(JVM)能够创建的最大线程大小。 |
newFixedThreadPool(ThreadPoolExecutor) | 创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程池达到最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行而异常结束,那么线程池会补充一个新的线程。 |
newSginleThreadExecutor(ThreadPoolExecutor) | 创建一个单线程的线程池。这个线程池只有一个工作线程,也就是相当于单线程串行执行所有任务。如果 这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。些线程池保证所有任务的执行顺序 会按照 任务的提交顺序 执行。 |
newScheduledThreadPool(ScheduledThreadPoolExecutor) | 创建一个大小无限的线程池。些线程池运行定时以及周期性执行任务的需求。 |
newSingleThreadScheduledExecutor(ScheduledThreadPoolExecutor) | 创建一个单线程用于定时以及周期性执行任务的需求。 |
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Demo06 {
public static void main(String[] args) {
Runnable r = new Demo06Runnable();
// ExecutorService es = Executors.newCachedThreadPool();
// ExecutorService es = Executors.newFixedThreadPool(2);
/*ExecutorService es = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
// execute就是线程代码
es.execute(r);
}*/
// ScheduledExecutorService es = Executors.newScheduledThreadPool(2);
ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();
System.out.println("准备执行:" + System.currentTimeMillis());
// 延迟执行
// es.schedule(r, 3, TimeUnit.SECONDS);
// 定时执行
// scheduleAtFixedRate(需要执行的线程, 第1个需要执行的线程延迟多长时间行, 两个线程间相隔的时间, 使用到时间单位)
es.scheduleAtFixedRate(r, 2, 5, TimeUnit.SECONDS);
// 关闭线程池
// es.shutdown();
}
}
class Demo06Runnable implements Runnable{
static long waitTime = 1000;
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "开始于" + System.currentTimeMillis());
synchronized (this) {
waitTime += 100;
}
Thread.sleep(waitTime);
System.out.println(Thread.currentThread().getName() + "结束于" + System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}