赞
踩
首先,我们要知道,线程池到底是不是越多越好呢?
在学习多线程之前,读者可能会有疑问?如果单线程跑得太慢,那么是否就能多创建多个线程来跑任务?并发的情况,线程是不是创建越多越好?这是一个很经典的问题,画图表示一下创建很多线程的情况,然后进行情况分析。
上下文切换(context switch):对于单核CPU来说,在一个时刻只能运行一个线程,对于并行来说,单核cpu也是可以支持多线程执行代码的,CPU是通过给线程分配时间片来解决的,所谓时间片是CPU给每个线程分配的时间,时间片的时间是非常短的,所以执行完成一个时间片后,进行任务切换,切换之前先保存这个任务的状态,以便于下次换回来的时候,可以加载这个任务的状态,所以从保存任务状态到再加载任务的过程称为上下文切换,不仅在线程间可以上下文切换,进程也同样可以
Executor : 接口类
ExecutorService:加入关闭方法和对Runnable、Callable、Future的支持
ScheduleExecutorService :加入对定时任务的支持
其中schedule(Runablle , long, Timeunit)和schedule(Callable , long, TimeUnit)表示的是多久后执行,而scheduleAtFixedRate方法和scheduleWithFixedDelay方法表示的都是周期性重复执行的
再描述scheduleAtFixedRate方法和scheduleWithFixedDelay方法的区别:
scheduleAtFixedRate:以固定的时间频率重复执行任务,如每10s ,也就是两个任务直接以固定的时间间隔执行,不管任务执行完成与否
scheduleWithFixedDelay:以固定的任务时延迟来重复执行任务,这种任务不管任务执行多久都执行完成,然后隔预定的如3s,接着执行下一个任务,每个任务之间的间隔都是一样的
Executors:快速得到线程池的工具类,创建线程池的工厂类
下面列举出ThreadPoolExecutor的主要参数:
虽然Executors使用起来很方便,不过在阿里编程规范里是强调了慎用Executors创建线程池,下面摘录自阿里编程规范手册:
【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors各个方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor:
主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。
2)newCachedThreadPool和newScheduledThreadPool:
主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。
ThreadPoolExecutor的基本参数:
画流程图表示,线程池的核心参数是corePoolSize、maxPoolSize、workQueue(工作队列)
线程池工作原理示意图:任务可以一直放,直到线程池满了的情况,才会拒绝,然后除了核心线程,其它的线程会被合理回收。所以正常情况下,线程池中的线程数量会处在 corePoolSize 与 maximumPoolSize 的闭区间内
ThreadPoolExecutor基本实例:
ExecutorService service = new ThreadPoolExecutor(2, 5,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(5));
service.execute(() ->{
System.out.println(String.format("thread name:%s",Thread.currentThread().getName()));
});
// 避免内存泄露,记得关闭线程池
service.shutdown();
ThreadPoolExecutor加上Callable、Future使用的例子:
public static void main(String[] args) {
ExecutorService service = new ThreadPoolExecutor(2, 5,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(5));
Future<Integer> future = service.submit(new CallableTask());
Thread.sleep(3000);
System.out.println("future is done?" + future.isDone());
if (future.isDone()) {
System.out.println("callableTask返回参数:"+future.get());
}
service.shutdown();
}
static class CallableTask implements Callable<Integer>{
@Override
public Integer call() {
return ThreadLocalRandom.current().ints(0, (99 + 1)).limit(1).findFirst().getAsInt();
}
}
java创建线程池的四种方式是:
1、newCachedThreadPool创建一个可缓存线程池;
2、newFixedThreadPool创建一个定长线程池;
3、newScheduledThreadPool创建一个定长线程池。
4、newSingleThreadExecutor
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
public void run() {
System.out.println(index);
}
});
}
}
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
public void run() {
try {
System.out.println(index);
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
public static void main(String[] args) {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
for (int i = 0; i < 10; i++) {
scheduledThreadPool.schedule(new Runnable() {
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
}
}
public static void main(String[] args) {
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
public void run() {
//System.out.println(index);
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。