笔记(三)--线程池+死锁

常见的线程池:

(1)Executors.newCacheThreadPool():可缓存线程池,先查看池中有没有以前建立的线程,如果有,就直接使用。如果没有,就建一个新的线程加入池中。(可无限扩充,负载较轻的情况使用)
(2) Executors.newFixedThreadPool(int n):创建一个可重用固定个数的线程池,以共享的无界队列方式来运行这些线程。(用于负载较重的情况使用,控制线程数量)
(3)Executors.newScheduledThreadPool(int n):创建一个定长线程池,支持定时及周期性任务执行(执行周期任务)
(4) Executors.newSingleThreadExecutor():创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

线程池的主要参数:

  • corePoolSize:(核心线程数)
    核心线程会一直存活,即使没有任务需要执行。 当线程数小于核心线程数时,即便此时存在空闲线程,也会通过创建一个新线程来执行该任务,直到已创建的线程数大于或等于corePoolSize时。设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭。
  • queueCapacity:任务队列容量(阻塞队列)
    核心线程数达到最大时,新任务会放在队列中排队等待执行。若队列满了,则判断最大可容量线程数。
  • maxPoolSize:(最大线程数)
    当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务。 当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常。
  • keepAliveTime:(线程空闲时间)
    当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize。 如果allowCoreThreadTimeout=true,则会直到线程数量=0。
  • allowCoreThreadTimeout:允许核心线程超时
  • rejectedExecutionHandler:任务拒绝处理器

过程:

任务进来时,首先执行判断,判断核心线程是否处于空闲状态,如果不是,核心线程就先就执行任务,如果核心线程已满,则判断任务队列是否有地方存放该任务,若果有,就将任务保存在任务队列中,等待执行,如果满了,再判断最大可容纳的线程数, 如果没有超出这个数量,就开创非核心线程执行任务,如果超出了,就调用handler实现拒绝策略。

拒绝策略:

(1)AbortPolicy 丢弃任务,抛运行时异常。 (2)CallerRunsPolicy 执行任务。
(3)DiscardPolicy 忽视,什么都不会发生。
(4)DiscardOldestPolicy 从队列中踢出最先进入队列
(最后一个执行)的任务,实现RejectedExecutionHandler接口,也可自定义处理器。

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

避免死锁:

在有些情况下死锁是可以避免的。三种用于避免死锁的技术:
(1)加锁顺序(线程按照一定的顺序加锁)
(2)加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
(3)死锁检测

猜你喜欢

转载自blog.csdn.net/njh1147394013/article/details/112344298