java 线程池
java线程池
什么是线程池?
线程池就是一个容器,把创建的若干个线程放入这个容器中,当处理任务需要运行线程时,线程池会将线程提交到任务队列中,处理完之后线程并不会被销毁,而是仍然处于线程中,等待下一任务,如果之后还有任务要使用这个线程,该线程会再次被提交到任务队列中。
使用线程池的优点
- java中创建线程,需要为线程分配一系列资源,假如创建线程的时间为t1,线程执行的任务时间为t2,线程销毁的时间为t3,而往往t1+t3>t2,频繁地创建和销毁线程效率将会非常低
2.线程池中的线程不会被销毁,有任务需要时,直接可以提交到任务队列 - 线程池可以统一分配线程,方便调优和监控,可以提高系统稳定性
线程池有哪些类型
1.newCachedThreadPool
一种可以缓存的线程池,若是线程池长度超过了处理需要,将会灵活回收空闲线程,若是没有课回收的线程,则会创建新的线程。该线程池容量为无限大,当执行第二个任务时,如果需要第一个已完成任务中执行过的线程,那么线程池可以重复调用,不需要重新创建新的线程。
实例代码如下:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
}
});
}
2 newFixedThreadPool
一种固定大小的线程池,可以控制线程最大并发数,超出的线程会在队列中等待,定长线程池的大小可以根据系统资源进行设置。
示例代码:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字
3 newScheduledThreadPool
一种定长的线程池,支持定时或者周期性地执行线程。
延迟3秒执行的示例代码:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
表示定长为5,延迟3秒执行的线程池
延迟1秒后每3秒执行一次,周期性执行的示例代码:
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);
4 newSingleThreadExecutor
一种单线程化的线程池,它会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。示例代码如下:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
结果按照顺序输出
线程池中的参数
- corePoolSize:核心池大小
- maximumPoolSize:线程池最大线程数。
- keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有线程数大于核心线程corePoolSize时,该参数才会起作用
- unit:参数keepAliveTime的时间单位
- workQueue:一个阻塞队列,用来存储等待执行的任务,有以下几种选择,ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue.
6.threadFactory:线程工厂,主要用来创建线程 - handler:便是当拒绝处理任务时的策略,四种取值:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由点用线程处理该任务。
线程池状态总结图:
参考博文:https://www.jianshu.com/p/174958a72ce9
https://www.cnblogs.com/ConstXiong/p/11686245.html