java - 如何分析Java中的多线程开销?
问题描述
我的程序如下所示:
Executor executor = Executors.newSingleThreadExecutor();
void work1(){
while (true) {
// do heavy work 1
Object data;
executor.execute(() -> work2(data));
}
}
void work2(Object data){
// do heavy work 2
}
我注意到,当work2
变得沉重时,它work1
也会影响。将进程分成两个线程几乎没有任何好处。
这种行为的原因可能是什么?我必须使用什么工具来查找和分析这些问题?
哦,这是我的机器规格:
解决方案
"while (true) {}" 工作速度很快,但 work2 很重而且工作很慢。结果,等待单线程的任务数无限增加。所以可用的核心内存耗尽,使用虚拟内存,速度要慢得多。标准线程池不是为处理大量任务而设计的。正确的解决方案如下:
class WorkerThread extends Thread {
ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
public void run() {
while true() {
queue.take().run();
}
}
}
WorkerThread workerThread = new WorkerThread();
workerThread.start();
void work1(){
while (true) {
Object data;
// do heavy work
workerThread.queue.put(() -> work2(data));
}
}
使用ArrayBlockingQueue
可以减少等待任务的数量。
推荐阅读
- flurl - 为发布请求创建方法时出错
- performance - Spring Boot Admin 高 cpu 使用率/详情页刷新间隔
- c++ - 从原生 iOS 应用程序与 QT 窗口交互
- reactjs - Material UI 默认表格排序
- java - 异常:com.fasterxml.jackson.core.JsonParseException:HttpMessageNotReadableException
- javascript - 使用反应钩子和打字稿为动作对象创建接口的正确方法是什么
- version - DotNewBrowser 上的 Chromium 新版本更新
- azure-iot-edge - 在 Azure IoT Edge 中管理机密的最佳方式是什么?
- c++ - AVR,在中断中使用 FIFO
- php - 如何向 Microsoft Graph Api 发布 GET 请求?