多线程 java 应用程序有时无法获取 Websphere 上的所有线程
Multithreading java application is failing sometimes to get all threads on Websphere
我有一个详尽的 java 应用程序 (JRE 1.8。0_201) 需要在线程中执行,它部署在 IBM Websphere 9 上。
在 WAS 启动时,应用程序执行似乎很好,但有时稍后会失去多线程功能,并且仅使用一个线程执行。
如果我们再次重启 websphere,情况就会恢复正常,执行将再次采用适当的并行线程。
是否缺少某些 WAS 配置?或者在 java 或 OS 侧?
Linux 上的硬件架构以下:
- 架构:x86_64
- CPU 运算模式(s):32 位、64 位
- 字节顺序:小端
- CPU (s): 4
- 在线CPU(s) 榜单:0-3
- 每核心线程数:1
- 每个插槽的核心数:1
- 插座(个):4
获取有关问题的最大信息:
线程转储
创建 JVM 中所有线程当前状态的列表。建议在几十 seconds/minutes 内重复执行此列表(在不同命名的输出中,不要覆盖你的转储),在你的情况下可能是几个小时。这允许您捕获更改和可能的死锁。如果什么都没有改变并且线程在同一行,那么可能有问题。
如何制作线程转储:
打开控制台(CMD),使用“cd”命令切换到“/Java/jdkx.x.x_xx /bin”(JDK)。然后输入“jstack JVM_PID > /thread_dump_1”。将“JVM_PID”替换为 运行 JVM 的进程 ID(任务管理器 - 详细信息 - PID 列)。
您还可以使用 VisualVM 等工具进行线程转储:
如何读取线程转储:
很棒的文章:https://dzone.com/articles/how-to-read-a-thread-dump
查找阻塞和等待线程。可能会有多个线程卡在同一条线上,只有一个线程取得一些进展。
在您的情况下如何读取线程转储:
我会在重新启动后立即进行一些线程转储,然后在出现问题时进行。如果你能区分一个线程何时结束,另一个线程何时有时间取得进展,我会制作另一个线程转储并比较它们(在第一次结束之前和第二次开始工作之后)。
Websphere 每个服务器都有一个线程池。
根据您的查询,我的理解是您有一个多线程程序,其中对创建的线程数没有限制。
因此,在这种情况下,websphere 会 运行 离开池中的所有线程,然后等待先前的线程关闭并将新线程分配给您的程序当新线程在其线程池中可用时。
我的第一个建议是向用户 Java 执行器池之类的多线程框架。
我建议您限制要创建的线程数。
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
//10 is the max number of threads for this threadpool
executor.execute(<your Runnable Object here>);
但是,如果您仍然不想限制,那么您可以使用:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
//This will create thread as and when needed however, this would have a better management of threads as compared to simply creating threads.
executor.execute(<your Runnable Object here>);
请注意,由于没有限制,您仍然可能 运行 线程和内存不足。
在 Webspehere 中,您可以在以下位置设置线程数:
服务器 --> 所有服务器 --> --> 附加属性 --> 线程池 --> WebContainer
最小尺寸,最大尺寸
我有一个详尽的 java 应用程序 (JRE 1.8。0_201) 需要在线程中执行,它部署在 IBM Websphere 9 上。
在 WAS 启动时,应用程序执行似乎很好,但有时稍后会失去多线程功能,并且仅使用一个线程执行。
如果我们再次重启 websphere,情况就会恢复正常,执行将再次采用适当的并行线程。
是否缺少某些 WAS 配置?或者在 java 或 OS 侧?
Linux 上的硬件架构以下:
- 架构:x86_64
- CPU 运算模式(s):32 位、64 位
- 字节顺序:小端
- CPU (s): 4
- 在线CPU(s) 榜单:0-3
- 每核心线程数:1
- 每个插槽的核心数:1
- 插座(个):4
获取有关问题的最大信息:
线程转储
创建 JVM 中所有线程当前状态的列表。建议在几十 seconds/minutes 内重复执行此列表(在不同命名的输出中,不要覆盖你的转储),在你的情况下可能是几个小时。这允许您捕获更改和可能的死锁。如果什么都没有改变并且线程在同一行,那么可能有问题。
如何制作线程转储:
打开控制台(CMD),使用“cd”命令切换到“/Java/jdkx.x.x_xx /bin”(JDK)。然后输入“jstack JVM_PID > /thread_dump_1”。将“JVM_PID”替换为 运行 JVM 的进程 ID(任务管理器 - 详细信息 - PID 列)。
您还可以使用 VisualVM 等工具进行线程转储:
如何读取线程转储:
很棒的文章:https://dzone.com/articles/how-to-read-a-thread-dump
查找阻塞和等待线程。可能会有多个线程卡在同一条线上,只有一个线程取得一些进展。
在您的情况下如何读取线程转储:
我会在重新启动后立即进行一些线程转储,然后在出现问题时进行。如果你能区分一个线程何时结束,另一个线程何时有时间取得进展,我会制作另一个线程转储并比较它们(在第一次结束之前和第二次开始工作之后)。
Websphere 每个服务器都有一个线程池。
根据您的查询,我的理解是您有一个多线程程序,其中对创建的线程数没有限制。
因此,在这种情况下,websphere 会 运行 离开池中的所有线程,然后等待先前的线程关闭并将新线程分配给您的程序当新线程在其线程池中可用时。
我的第一个建议是向用户 Java 执行器池之类的多线程框架。 我建议您限制要创建的线程数。
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
//10 is the max number of threads for this threadpool
executor.execute(<your Runnable Object here>);
但是,如果您仍然不想限制,那么您可以使用:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
//This will create thread as and when needed however, this would have a better management of threads as compared to simply creating threads.
executor.execute(<your Runnable Object here>);
请注意,由于没有限制,您仍然可能 运行 线程和内存不足。
在 Webspehere 中,您可以在以下位置设置线程数: 服务器 --> 所有服务器 --> --> 附加属性 --> 线程池 --> WebContainer 最小尺寸,最大尺寸