文章目录
  1. 第八章、Java中的并发工具类
    1. 8.1、CountDownLatch
    2. 8.2、CyclicBarrier
    3. 8.3、控制并发线程数的Semaphore
    4. 8.4、线程交换数据Exchanger
  2. 第九章、Java线程池
    1. 9.1、Java线程池模型
    2. 9.2、线程池的使用
      1. 1、参数部分
      2. 2、提交任务
      3. 3、线程池的关闭
      4. 4、合理的配置线程池

第八章、Java中的并发工具类

8.1、CountDownLatch

  • 多线程的计数器,控制并发

    8.2、CyclicBarrier

  • 构造屏障,直到最后一个线程到达后才执行所有线程
  • 高级的构造函数CyclicBarrier(int, Runnable),线程到达屏障后,优先执行Runnable
  • reset方法可以重置,而CountDownLatch无法重置,只可使用一次

    8.3、控制并发线程数的Semaphore

  • 控制线程的并发数

    8.4、线程交换数据Exchanger

  • 第一个线程执行Exchange方法,其会等待第二个线程执行Exchange
  • 可用于遗传算法

第九章、Java线程池

9.1、Java线程池模型

Java线程池示意图

  • 关于全局锁,见源码mainLock,用于锁存放线程Worker(对于用户线程的再次封装)的HashSet

    9.2、线程池的使用

    1、参数部分

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    /**
    * Creates a new {@code ThreadPoolExecutor} with the given initial
    * parameters.
    *
    * @param corePoolSize 基本的核心线程数,如果调用prestartAllCoreThreads则线程池会提前创建并启动所有基本线程
    * @param maximumPoolSize 线程池最大数量,如果BlockingQueue无穷大则无效果(Thread只会不断进入Queue中)
    * @param keepAliveTime 核心线程之外的线程空闲时候的保持时间,任务很多而执行较快可以调大;默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0
    * @param unit keepAliveTime的时间单位
    * @param workQueue 用于保存等待执行任务的阻塞队列
    * @param threadFactory 创建线程的工厂,可以通过其给每个创建出来的线程设置有意义的名字,guava可以快速的配置这类线程工厂(new ThreadFactoryBuilder().setNameFormat("XX-task-%d").build())
    * @param handler 饱和策略,当队列和线程池都满时,执行,默认有四种
    * ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
    * ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
    * ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    * ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
    * @throws IllegalArgumentException if one of the following holds:<br>
    * {@code corePoolSize < 0}<br>
    * {@code keepAliveTime < 0}<br>
    * {@code maximumPoolSize <= 0}<br>
    * {@code maximumPoolSize < corePoolSize}
    * @throws NullPointerException if {@code workQueue}
    * or {@code threadFactory} or {@code handler} is null
    */
    public ThreadPoolExecutor(int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    ThreadFactory threadFactory,
    RejectedExecutionHandler handler)

2、提交任务

  • submit提交有返回值的任务,相反用execute

    3、线程池的关闭

  • shutdownNow:首先将线程池状态变为STOP,尝试所有正在执行或暂停的任务,返回等待的任务列表(BQueue中的),如果任务不一定要执行完,则使用这种
  • shutdown:将状态设置为SHUTDOWN,之后中断所有没有正在执行的任务,一般使用shutdown

    4、合理的配置线程池

  • CPU密集型任务应配置尽可能小的线程,IO密集型任务由于并不是一直在执行任务,则应配置尽可能多的线程,如2*CPU_NUM
  • 混合型任务可以考虑拆分为一个CPU型与IO型
  • 优先级不同的任务考虑使用优先级队列,但是会出现饥饿问题
  • 依赖数据库连接池的任务,应该设置线程数较大,更好的使用CPU
  • 使用有界队列,增强预警能力
文章目录
  1. 第八章、Java中的并发工具类
    1. 8.1、CountDownLatch
    2. 8.2、CyclicBarrier
    3. 8.3、控制并发线程数的Semaphore
    4. 8.4、线程交换数据Exchanger
  2. 第九章、Java线程池
    1. 9.1、Java线程池模型
    2. 9.2、线程池的使用
      1. 1、参数部分
      2. 2、提交任务
      3. 3、线程池的关闭
      4. 4、合理的配置线程池