java线程池运行流程

用户线程(ULT):不需要内核支持而在用户程序中实现线程,不依赖操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程得函数控制用户线程。另外,用户线程是由应用进程利用线程库创建和管理,不依赖操作系统核心。不需要用户态/核心态切换,速度快,操作系统内核不知道多线程得存在,因此一个线程阻塞,将使得整个进程阻塞。(操作系统感知不到内部创建的多个线程,当一个线程执行的时候,操作系统不会分配另外的cpu给其它的用户线程)

内核线程(KLT):线程的所有管理操作由操作系统完成。内核保存了线程状态和上下文信息,当一个线程执行了引起阻塞的系统调用时,内核可以调度该进程其它线程执行。在多处理器系统上,内核可以分配属于同一进程的多个线程在多个处理器上运行,提高进程执行并发度。由于内核完成线程的创建、调度和管理,所以和用户线程相比操作慢得多,但是仍然比进程的创建和管理操作要快。

为什么使用线程池?
线程是一种稀缺资源,它的创建与销毁是一个相对偏重且耗资源的操作,而java线程依赖内核线程,其线程创建需要进行操作系统状态切换,为避免资源过度消耗设法重用线程执行多个任务,线程池就是一个线程缓存,负责对线程进行统一分配、调度和监控。

线程池的执行流程
在这里插入图片描述

比如当前有100个任务,线程池核心线程数4,最大线程数为6

  1. 当执行execute方法,4个任务直接进入核心线程池并运行
  2. 剩下的94个任务进入任务队列(ArrayBlockingQueue和LinkedBlockingQueue都是有界队列,不过LinkedBlockingQueue已经够用了,默认是长度是Integer.MAX_VALUE)等待执行。
  3. 当队列满时,剩下的任务放入非核心线程池中执行。
  4. 当队列和非核心线程池都满足,执行拒绝策略:
    • ThreadPoolExecutor.AbortPolicy() — 抛出java.util.concurrent.RejectedExecutionException异常
    • ThreadPoolExecutor.CallerRunsPolicy() — 重试添加当前的任务,他会自动重复调用execute()方法
    • ThreadPoolExecutor.DiscardOldestPolicy() — 抛弃旧的任务
    • ThreadPoolExecutor.DiscardPolicy() — 抛弃当前的任务
发布了39 篇原创文章 · 获赞 3 · 访问量 3344

猜你喜欢

转载自blog.csdn.net/administratorJWT/article/details/105633396
今日推荐