加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 移动互联 > 评测 > 正文

3年工作经验,工作中还不会使用多线程?阿里P6:别慌,我都总结好了

发布时间:2019-07-20 17:49:06 所属栏目:评测 来源:Jay_huaxiao
导读:掌握线程池是后端程序员的基本要求,相信大家求职面试过程中,几乎都会被问到有关于线程池的问题。我在网上搜集了几道经典的线程池面试题,并以此为切入点,谈谈我对线程池的理解。如果有哪里理解不正确,非常希望大家指出,接下来大家一起分析学习吧。 经

工作机制:

3年工作经验,工作中还不会使用多线程?阿里P6:别慌,我都总结好了
  • 提交任务
  • 如果线程数少于核心线程,创建核心线程执行任务
  • 如果线程数等于核心线程,把任务添加到LinkedBlockingQueue阻塞队列
  • 如果线程执行完任务,去阻塞队列取任务,继续执行。

实例代码

  1. ExecutorService executor = Executors.newFixedThreadPool(10); 
  2.  for (int i = 0; i < Integer.MAX_VALUE; i++) { 
  3.  executor.execute(()->{ 
  4.  try { 
  5.  Thread.sleep(10000); 
  6.  } catch (InterruptedException e) { 
  7.  //do nothing 
  8.  } 
  9.  }); 
  10. 复制代码 

IDE指定JVM参数:-Xmx8m -Xms8m :

3年工作经验,工作中还不会使用多线程?阿里P6:别慌,我都总结好了

run以上代码,会抛出OOM:

3年工作经验,工作中还不会使用多线程?阿里P6:别慌,我都总结好了

因此,面试题:使用无界队列的线程池会导致内存飙升吗?

答案 :会的,newFixedThreadPool使用了无界的阻塞队列LinkedBlockingQueue,如果线程获取一个任务后,任务的执行时间比较长(比如,上面demo设置了10秒),会导致队列的任务越积越多,导致机器内存使用不停飙升, 最终导致OOM。

使用场景

FixedThreadPool 适用于处理CPU密集型的任务,确保CPU在长期被工作线程使用的情况下,尽可能的少的分配线程,即适用执行长期的任务。

newCachedThreadPool

  1. public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { 
  2.  return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 
  3.  60L, TimeUnit.SECONDS, 
  4.  new SynchronousQueue<Runnable>(), 
  5.  threadFactory); 
  6.  } 
  7. 复制代码 

线程池特点:

  • 核心线程数为0
  • 最大线程数为Integer.MAX_VALUE
  • 阻塞队列是SynchronousQueue
  • 非核心线程空闲存活时间为60秒

当提交任务的速度大于处理任务的速度时,每次提交一个任务,就必然会创建一个线程。极端情况下会创建过多的线程,耗尽 CPU 和内存资源。由于空闲 60 秒的线程会被终止,长时间保持空闲的 CachedThreadPool 不会占用任何资源。

工作机制

3年工作经验,工作中还不会使用多线程?阿里P6:别慌,我都总结好了
  • 提交任务
  • 因为没有核心线程,所以任务直接加到SynchronousQueue队列。
  • 判断是否有空闲线程,如果有,就去取出任务执行。
  • 如果没有空闲线程,就新建一个线程执行。
  • 执行完任务的线程,还可以存活60秒,如果在这期间,接到任务,可以继续活下去;否则,被销毁。

实例代码

  1.  ExecutorService executor = Executors.newCachedThreadPool(); 
  2.  for (int i = 0; i < 5; i++) { 
  3.  executor.execute(() -> { 
  4.  System.out.println(Thread.currentThread().getName()+"正在执行"); 
  5.  }); 
  6.  } 
  7. 复制代码 

运行结果:

3年工作经验,工作中还不会使用多线程?阿里P6:别慌,我都总结好了

使用场景

用于并发执行大量短期的小任务。

newSingleThreadExecutor

  1. public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { 
  2. return new FinalizableDelegatedExecutorService 
  3. (new ThreadPoolExecutor(1, 1, 
  4. 0L, TimeUnit.MILLISECONDS, 
  5. new LinkedBlockingQueue<Runnable>(), 
  6. threadFactory)); 
  7. 制代码 

线程池特点

  • 核心线程数为1
  • 最大线程数也为1
  • 阻塞队列是LinkedBlockingQueue
  • keepAliveTime为0

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读