| public class ExecutorDemo { |
| |
| public static void main(String[] args) { |
| |
| ExecutorService executorService = Executors.newCachedThreadPool(); |
| |
| ExecutorService executorService1 = Executors.newFixedThreadPool(2); |
| |
| ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); |
| |
| ExecutorService executorService2 = Executors.newWorkStealingPool(); |
| |
| ExecutorService executorService3 = Executors.newSingleThreadExecutor(); |
| |
| ScheduledExecutorService scheduledExecutorService1 = Executors.newSingleThreadScheduledExecutor(); |
| |
| |
| executorService.submit(() -> { |
| System.out.println(Thread.currentThread().getName()); |
| }); |
| } |
| |
| } |
| newCachedThreadPool:创建一个可以根据需要创建新线程的线程池,如果有空闲线程,优先使用空闲的线程 |
| # 查看源码 |
| public static ExecutorService newCachedThreadPool() { |
| return new ThreadPoolExecutor(0, Integer.MAX_VALUE, |
| 60L, TimeUnit.SECONDS, |
| new SynchronousQueue<Runnable>()); |
| } |
| |
| newFixedThreadPool:创建一个固定大小的线程池,在任何时候,最多只有N个线程在处理任务 |
| newScheduledThreadPool:能延迟执行、定时执行的线程池 |
| newWorkStealingPool:工作窃取,使用多个队列来减少竞争 |
| newSingleThreadExecutor:单一线程的线程池,只会使用唯一一个线程来执行任务,即使提交再多的任务,也都是会放到等待队列里进行等待 newSingleThreadScheduledExecutor:单线程能延迟执行、定时执行的线程池 |
| 尽量避免使用Executor框架创建线程池 |
| newFixedThreadPool newSingleThreadExecutor 允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM |
| newCachedThreadPool newScheduledThreadPool 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM |
| public class OOMDemo { |
| |
| public static void main(String[] args) { |
| |
| ExecutorService executorService = Executors.newFixedThreadPool(2); |
| |
| while (true) { |
| executorService.submit(() -> { |
| System.out.println(Thread.currentThread().getName()); |
| try { |
| Thread.sleep(3000L); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| }); |
| } |
| } |
| |
| } |
| -Xms60m |
| -Xmx60m |
| -XX:+HeapDumpOnOutOfMemoryError |
| -XX:HeapDumpPath=C:\work |
| # C:\work路径下生成文件 |
| |
| pool-1-thread-1 |
| pool-1-thread-2 |
| java.lang.OutOfMemoryError: Java heap space |
| Dumping heap to C:\work\java_pid7132.hprof ... |
| Heap dump file created [113116988 bytes in 0.993 secs] |
| |
| Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main" |
| |
| Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "pool-1-thread-1" |
| |
| Process finished with exit code 1 |

| # 在限定了堆的内存之后,还会把整个电脑的内存撑爆 |
| # 创建线程时用的内存并不是我们制定jvm堆内存,而是系统的剩余内存 |
| |
| public class OOMDemo2 { |
| |
| public static void main(String[] args) { |
| |
| ExecutorService executorService = Executors.newCachedThreadPool(); |
| while (true) { |
| executorService.submit(() -> { |
| System.out.println(Thread.currentThread().getName()); |
| try { |
| Thread.sleep(3000L); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| }); |
| } |
| } |
| |
| } |
| 创建线程池时,核心线程数不要过大 |
| 相应的逻辑,发生异常时要处理 |
| submit 如果发生异常,不会立即抛出,而是在get的时候,再抛出异常 |
| execute 直接抛出异常 |
| public class OOMDemo3 { |
| |
| public static void main(String[] args) throws ExecutionException, InterruptedException { |
| |
| ExecutorService executorService = Executors.newFixedThreadPool(2); |
| for (int i = 0; i < 100; i++) { |
| Future<Integer> submit = executorService.submit(() -> { |
| System.out.println(Thread.currentThread().getName()); |
| return 1 / 0; |
| }); |
| submit.get(); |
| } |
| } |
| |
| } |
| |
| # 控制台打印结果 |
| pool-1-thread-1 |
| Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero |
| at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122) |
| at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191) |
| at com.xdclass.pool.OOMDemo3.main(OOMDemo3.java:22) |
| Caused by: java.lang.ArithmeticException: / by zero |
| at com.xdclass.pool.OOMDemo3.lambda$main$0(OOMDemo3.java:19) |
| at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) |
| at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) |
| at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) |
| at java.base/java.lang.Thread.run(Thread.java:834) |
| public class OOMDemo3 { |
| |
| public static void main(String[] args) throws ExecutionException, InterruptedException { |
| |
| ExecutorService executorService = Executors.newFixedThreadPool(2); |
| for (int i = 0; i < 100; i++) { |
| executorService.execute(() -> { |
| System.out.println(Thread.currentThread().getName()); |
| int j=1/0; |
| }); |
| } |
| } |
| |
| } |
| |
| # 控制台打印结果 |
| pool-1-thread-24 |
| Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero |
| at com.xdclass.pool.OOMDemo3.lambda$main$0(OOMDemo3.java:19) |
| at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) |
| at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) |
| at java.base/java.lang.Thread.run(Thread.java:834) |
| Exception in thread "pool-1-thread-3" Exception in thread "pool-1-thread-2" java.lang.ArithmeticException: / by zero |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
2021-05-16 真实机中安装CentOS7(一)