【Java实战】线程池 并发 并行 生命周期(详细解释)

#新星杯·14天创作挑战营·第11期#

线程池:
一种复用线程的技术

不使用线程池的问题:
用户每提出一个需求,都要创建一个新的线程。

创建线程池的方法:
JDK 5.0起提供了一个代表线程池的接口:ExecutorService。

方式一:
使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。

public ThreadPoolExecutor(
int corePoolSize, 
int maximumPoolSize,                         
long keepAliveTime,                       
TimeUnit unit,                         
BlockingQueue<Runnable> workQueue,                         
ThreadFactory threadFactory,                         
RejectedExecutionHandler handler)

参数详细解析
参数一: corePoolSize(核心线程数)
意义:线程池中保持存活的最小线程数量,即使它们处于空闲状态。

参数二: maximumPoolSize(最大线程数)
意义:线程池允许创建的最大线程数量。

参数三:keepAliveTime(线程空闲时间)
意义:当线程数超过核心线程数时,多余的空闲线程在终止前等待新任务的最长时间。

参数四:unit(时间单位)
意义:keepAliveTime参数的时间单位。

参数五:workQueue(工作队列)
意义:用于保存等待执行的任务的阻塞队列。

参数六:threadFactory(线程工厂)
意义:用于创建新线程的工厂。

参数七:handler(拒绝策略)
意义:当线程池和工作队列都达到饱和状态时(即线程数达到maximumPoolSize且队列已满),对新任务采取的处理策略。

类比理解:
参数一 正式工:3
参数二 最大员工数:5 临时工:2
参数三四 临时工空闲多久被开除
参数五 客人排队的地方
参数六 负责招聘的hr
参数七 忙不过来怎么办?

代码演示:

public class ThreadPoolTestpublic static void main(String[] args)new ThreadPoolExecutor(358TimeUnit.SECOND,new LinkedBlockingQuene<>(),Executors.defaultThreadFactory(),new ThreadPoolExexutor.AbortPolicy());
  }
}

说明:

workQueue实现类:
LinkedBlockingQuene不限制大小
ArrayBlockingQuene可控制大小

线程工厂:
Executors.defaultThreadFactory()

处理策略:
ThreadPoolExexutor.AbortPolicy()
可抛出异常。

线程池的注意事项:
1.临时线程什么时候创建?
新任务提交时核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建。
2.什么时候会开始拒绝新任务?
核心线程和临时线程都在忙,任务队列也满了,新的任务过来会拒绝新的任务。

线程池处理Runnable任务
execute()方法:
线程池会自动创建一个线程池,自动执行

\\创建一个Runnable对象
public class MyRunnable implements Runnable{
 @Override
 public void run(){
System.out.println(Thread.currentThread().getName());
try{
Thread.sleep(1000);
}catch(Exception e){
  e.printStackTrace();
}
}
}

```java
public class ThreadPoolTestpublic static void main(String[] args)new ThreadPoolExecutor(358TimeUnit.SECOND,new LinkedBlockingQuene<>(),Executors.defaultThreadFactory(),new ThreadPoolExexutor.AbortPolicy());
 Runnable target=new MyRunnable();
 pool.execute(target);
 //自动创建一个新线程,自动执行
  }
}

shutdown()
等线程池的任务全部执行完毕,再关闭线程池

pool.shutdown();

shutdownNow()
立即关闭线程池

pool.shutdownNow();

线程池处理Callable方法
Future<> submit()

//定义一个任务类,实现Callable接口
public class MyCallable implement CallableString>{
private int n;
public MyCallable(int n)this.n=n;//重写Callable的call方法
@Override
public String call() throwException{
//描述线程的任务就是返回线程执行返回的结果
int sum=0;
for(int i=0;i<=n;i++){
sum+=i;return Thread.currentThraed.getName()+sum;
}}


public class ThreadPoolTestpublic static void main(String[] args)new ThreadPoolExecutor(358TimeUnit.SECOND,new LinkedBlockingQuene<>(),Executors.defaultThreadFactory(),new ThreadPoolExexutor.AbortPolicy());
//创建Callable任务
Futuer<String> f1=pool.submit(new MyCallable(100)); 
 //自动创建一个新线程,自动执行
  }
}

方式二:
使用**Executor(线程池工具类)**调用方法返回不同特点的线程池对象。

在这里插入图片描述

public class ThreadPoolTestpublic static void main(String[] args)//创建固定数量线程的线程池
  Executor pool=Executor.newFixedThreadPool(3);

说明:底层还是通过实现类创建的线程池对象

核心线程配置:
计算密集型任务:核心线程数量=CPU的核数+1
IO密集型任务:核心线程数量=CPU的核数×2

**CPU的核数:**ctrl alt delete调出任务管理器,性能中可查

Executors使用可能存在的陷阱
大型并发型系统环境中使用Executors如果不注意可能会出现系统风险。

并发/并行
进程:
正在运行的程序(软件)就是一个独立的进程
线程是属于进程的,一个进程中可以同时运行很多个线程。
进程中的多个线程其实都是并发和并行执行的。

并发的含义:
进程中的线程是由CPU负责调度执行的,到CPU能同时处理线程的数量有限,为了保证全部线程都能往前执行,CPU会为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉是这些线程在同时执行,这就是并发。

并行的含义
在同一个时刻上,同时有多个线程在被CPU调度执行。

思考:
多线程到底是怎么在执行?
并发和并行同时进行。

线程的生命周期
线程从生到死的过程,经历各种状态和状态转换。

Thread.State();

6种状态
在这里插入图片描述
New新建->start()
->Runnable可运行->执行完毕出现异常
->Teminated被终止

Blocked锁堵塞
Waiting无限等待
Timed Waiting计时等待

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值