并发编程:线程池使用

 

  • 线程池大小计算公式

  N_thread = N_cpu * U_cpu * (1+W/C)

  U_cpu: target of CPU utilization

  W/C: rate of wait time to compute time

  • 配置ThreadPoolExecutor
  public ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,     
BlockingQueue<Runnable> workQueue,     ThreadFactory threadFactory,
   
RejectedExecutionHandler handler) {};   
  1. newFixedThreadPool和newSingleThreadPool:在默认情况下使用无界的LinkedBlockingQueue
  2. newSingleThreadPool:通过线程封闭来实现线程安全性
  3. SynchronousQueue:不是真正的队列,是一种在线程之间的进行移交的机制,只有当线程池是无界或者可以拒绝服务时,才有实际价值
  4. newCachedThreadPool:使用了SynchronousQueue,有更好的排队性能。在没有任务执行时,当线程的空闲时间超过keepAliveTime,会自动释放线程资源,当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定的系统开销
  5. 只有当任务相对独立时,为线程池或工作队列设置界限才是合理的,任务有依赖,则可能导致“饥饿”死锁问题
  6. 队列饱和策略:AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy
  7. 调用者运行(CallerRunsPolicy):服务器过载时,从线程池->工作队列->应用程序->TCP层,实现一种平缓的性能降低
  8. 通过Semaphore(信号量)来控制任务的提交速率: new Semaphore(bound),acquire()获取一个许可,release()释放
  9. ThreadFactory可以自定义
  10. keepAliveTime:线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间;默认情况下,该参数只在线程数大于corePoolSize时才有用;
  11. 线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,前提是当前线程数小于maximumPoolSize;
  • 扩展ThreadPoolExecutor
  1. beforeExecute和afterExecute:可以添加日志、计时、监视和统计信息收集
  2. 线程池操作完成关闭操作时调用terminated

 参考:深入分析java线程池的实现原理

posted @ 2017-04-10 23:44  感遇  阅读(231)  评论(0)    收藏  举报