一 线程池
1.1 概念
线程池(英语:thread pool):一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。
1.2 优点
1.降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的销耗。
2.提高响应速度: 当任务到达时,任务可以不需要等待线程创建就能立即执行。
3.提高线程的可管理性: 线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
1.3 线程池架构
Java 中的线程池是通过 Executor 框架实现的,该框架中用到了 Executor,Executors,ExecutorService,ThreadPoolExecutor 这几个类。
通过查看线程池创建对象的类源代码,newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor 都有new ThreadPoolExecutor
?二???常见线程池实现方式
2.1 常见线程池
Java通过Executors提供四种线程池,分别为:
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。 newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
2.2?newFixedThreadPool
1.思路:创建一个定长线程池,10个任务,每个任务自己循环10次输出。分配给3个线程。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()
匿名调用方式
?2.常规调用代码
public class AppleResources implements Runnable {
public int task=0;
public AppleResources(int task) {
this.task = task;
}
@Override
public void run() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<10;j++){
System.out.println(Thread.currentThread().getName()+" 正在进行第"+task+"个任务,第"+j+"次循环");
}
}
}
2.调用
public class FixdThreadPool {
public static void main(String[] args) {
//创建一个初始线程为3个的线程池
ExecutorService pool= Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++){//10个任务
final int task=i;
pool.execute(new AppleResources(i));//每个任务循环10次
}
System.out.println("all of ten tasks have committed");
//关闭线程池
pool.shutdown();
}
}
3、结果
2.3?newCachedThreadPool
逻辑:创建一个可缓存的线程池,10个任务,每个任务自己循环10次输出。根据情况自动分配线程,创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
1.代码:
public class AppleResources implements Runnable {
public int task=0;
public AppleResources(int task) {
this.task = task;
}
@Override
public void run() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<10;j++){
System.out.println(Thread.currentThread().getName()+" 正在进行第"+task+"个任务,第"+j+"次循环");
}
}
}
2.调用
public class CachedThreadPool {
public static void main(String[] args) {
//创建一个初始线程为3个的线程池
ExecutorService pool= Executors.newCachedThreadPool();
for(int i=0;i<10;i++){//10个任务
final int task=i;
pool.execute(new AppleResources(i));//每个任务循环10次
}
System.out.println("all of ten tasks have committed");
//关闭线程池
pool.shutdown();
}
}
3.调取结果部分截图:
?2.4??newScheduledThreadPool
1.思路:10个任务,每个任务自己循环10次输出。分配给5个线程,创建一个定长线程池,支持定时及周期性任务执行
2.代码
public class AppleResources implements Runnable {
public int task=0;
public AppleResources(int task) {
this.task = task;
}
@Override
public void run() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<10;j++){
System.out.println(Thread.currentThread().getName()+" 正在进行第"+task+"个任务,第"+j+"次循环");
}
}
}
?3.调用
package com.ljf.thread.pool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: ScheduleThreadPool
* @Description: TODO
* @Author: liujianfu
* @Date: 2022/05/08 19:16:01
* @Version: V1.0
**/
public class ScheduleThreadPool {
public static void main(String[] args) {
//创建一个初始线程为3个的线程池
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
for(int i=0;i<10;i++){//10个任务
//scheduledThreadPool.schedule(new AppleResources(i), 3, TimeUnit.SECONDS);//每个任务循环10次
scheduledThreadPool.scheduleAtFixedRate(new AppleResources(i), 1,5, TimeUnit.SECONDS);
}
System.out.println("all of ten tasks have committed");
//关闭线程池
// scheduledThreadPool.shutdown();
}
}
4.展示:表示延迟1秒后每3秒执行一次。
??2.5???newSingleThreadExecutor
1.思路:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行,10个任务,每个任务自己循环10次输出。分配给1个线程。
2代码
package com.ljf.thread.pool;
/**
* @ClassName: AppleResources
* @Description: TODO
* @Author: liujianfu
* @Date: 2022/05/08 18:09:05
* @Version: V1.0
**/
public class AppleResources implements Runnable {
public int task=0;
public AppleResources(int task) {
this.task = task;
}
@Override
public void run() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int j=0;j<10;j++){
System.out.println(Thread.currentThread().getName()+" 正在进行第"+task+"个任务,第"+j+"次循环");
}
}
}
3.调用
public class SingleThreadPool {
public static void main(String[] args) {
//创建一个初始线程为3个的线程池
ExecutorService pool = Executors.newSingleThreadExecutor();
for(int i=0;i<10;i++){//10个任务
final int task=i;
pool.execute(new AppleResources(i));//每个任务循环10次
}
System.out.println("all of ten tasks have committed");
//关闭线程池
pool.shutdown();
}
}
4.结果:?
?https://www.iteye.com/blog/cuisuqiang-2019372
https://www.iteye.com/blog/huxc-2179106
|