徐无忌并发编程笔记:如果在线程池中使用无界阻塞队列会发生什么问题?

完成:第一遍

1.什么是无界阻塞队列?

LinkedBlockingQueue默认的最大任务数量是Integer.MAX_VALUE

如果线程池内的线程在获取到一个任务后,需要执行时间较长,会导致workQueue里积压的任务越来越多

2.什么是OOM?

大量任务的积压导致机器的内存使用不停的飙升,最后导致OOM

OOM,“Out Of Memory”,俗称“内存用完了”。
当JVM因为没有足够的内存来为新的对象分配空间,并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(非exception,因为这个问题已经非常严重到不足以被应用处理)

3.为什么会OOM?为什么会没有内存了呢?

原因主要有两点:

原因1:分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少

原因2:应用用的太多,用完没释放浪费了,此时就会造成内存泄露或者内存溢出

4.什么是内存泄露或者内存溢出?

内存泄露:申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了,因为申请者不用了,而又不能被虚拟机分配给别人用

内存溢出:申请的内存超出了JVM能提供的内存大小,此时称之为溢出

5.如果存在远程服务调用,使用无界阻塞队列,可能会出现什么情况?

远程服务调用,使用无界阻塞队列,如果线程池内的线程接到一个任务后,需要执行时间较长,大量任务的积压导致机器的内存使用不停的飙升,最后会导致OOM

6.案例:无界阻塞队列在Java中一个具体的使用场景

public static ExecutorService   newSingleThreadExecutor(){
   return new FinalizableDelegatedExecutorService(
   new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

参数:corePoolSize和maxPoolSize设置为1,线程池内只有一个线程
参数:通过LinkedBlockingQueue无界队列将任务进行排队,保证了串行执行所有任务,所有任务肯定是绝对顺序执行

使用线程池时慎用无界队列,一般情况下针对特定场景才会进行使用