1、LinkedBlockingQueue报错
package com.spring.pro.threadpool.completableFuture.youhua.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
/**
* @Title: ExecutorsDemo.java
* @ProjectName com.spring.pro.threadpool
* @Description:
* @author ybwei
* @date 2020年1月3日 下午7:26:22
*/
@Slf4j
public class ThreadPoolTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < Integer.MAX_VALUE; i++) {
executor.execute(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
log.info("线程错误:", e);
}
});
}
}
}
JVM参数-Xmx5m -Xms5m
异常:
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.concurrent.LinkedBlockingQueue.offer(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source)
at com.spring.pro.threadpool.completableFuture.youhua.test.ThreadPoolTest.main(ThreadPoolTest.java:22)
OOM描述:
JVM抛出 java.lang.OutOfMemoryError: GC overhead limit exceeded 错误就是发出了这样的信号: 执行垃圾收集的时间比例太大, 有效的运算量太小. 默认情况下, 如果GC花费的时间超过 98%, 并且GC回收的内存少于 2%, JVM就会抛出这个错误。
OOM原因:
newFixedThreadPool中创建的LinkedBlockingQueue,是无界队列。不断向队列添加任务就会导致内存溢出。
2、ArrayBlockingQueue报错
上面的例子只是造成OOM的一个demo,实际上
package com.spring.pro.threadpool.completableFuture.test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
/**
* @Title: CompletableFutureTest.java
* @ProjectName com.spring.pro.threadpool
* @Description:
* @author ybwei
* @date 2020年1月3日 下午4:29:25
*/
@Slf4j
public class CompletableFutureTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ArrayBlockingQueue<Runnable> arrayWorkQueue = new ArrayBlockingQueue<>(400000);
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, // corePoolSize线程池中核心线程数
10, // maximumPoolSize 线程池中最大线程数
60, // 线程池中线程的最大空闲时间,超过这个时间空闲线程将被回收
TimeUnit.SECONDS, // 时间单位
// 下面是采用有界队列和无界队列的区别
arrayWorkQueue,
// linkedWorkQueue,
// 下面是jdk的四种执行策略
// new ThreadPoolExecutor.AbortPolicy() 这种策略直接抛出异常,丢弃任务。
// new ThreadPoolExecutor.DiscardPolicy() 这种策略和AbortPolicy几乎一样,也是丢弃任务,只不过他不抛出异常。
new ThreadPoolExecutor.CallerRunsPolicy() // 线程调用运行该任务的 execute,调用者运行者
// 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。没看明白,当时是我的main线程执行的task5
// new ThreadPoolExecutor.DiscardOldestPolicy()// 如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)
);
log.info("线程开始");
handle(threadPool);
log.info("线程结束");
}
/**
* @Description:
* @param threadPool
* @Author: ybwei
* @Date: 2020年1月3日 下午7:43:56
*/
private static void handle(ThreadPoolExecutor threadPool) {
for(int i=0;i<Integer.MAX_VALUE;i++) {
CompletableFuture.runAsync(() -> {
try {
log.info("运行开始");
TimeUnit.SECONDS.sleep(10);
log.info("运行结束");
} catch (InterruptedException e) {
}
log.info("run end ...");
},threadPool);
}
}
}
JVM参数-Xmx5m -Xms5m,依然会报OOM。因为队列太长了new ArrayBlockingQueue<>(400000)。