如何分析Java中的多线程开销?

huangapple go评论78阅读模式
英文:

How to analyze multi-threading overhead in Java?

问题

以下是翻译好的代码部分:

我的程序看起来像这样

Executor executor = Executors.newSingleThreadExecutor();

void work1(){
    while (true) {
        // 进行繁重的工作 1
        Object data;
        executor.execute(() -> work2(data));
    }
}

void work2(Object data){
    // 进行繁重的工作 2
}

请注意,这只是代码的翻译部分,不包括问题的回答部分。

英文:

My program looks like this:

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
}

I noticed that when work2 becomes heavy it affects work1 as well. It gets to the point when there is almost no gain in splitting the process into two threads.

What could be the reasons for this behavior and what tools do I have to find and analyze those problems?

Oh and here are my machine specs:

如何分析Java中的多线程开销?

答案1

得分: 1

"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;
        // 进行繁重的工作
        workerThread.queue.put(() -> work2(data));
    }
}

使用 ArrayBlockingQueue 可以保持等待任务的数量较小。

英文:

"while (true) {}" works fast but work2 is heavy and works slow. As a result, the number of tasks waiting for the single thread increases infinitely. So available core memory is exhausted and virtual memory is used, which is much slower. Standard thread pool is not designed to handle large number of tasks. A correct solution is as follows:

class WorkerThread extends Thread {
    ArrayBlockingQueue&lt;Runnable&gt; queue = new ArrayBlockingQueue&lt;&gt;(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(() -&gt; work2(data));
    }
 }

Using ArrayBlockingQueue keeps number of waiting tasks small.

huangapple
  • 本文由 发表于 2020年8月10日 02:17:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/63329787.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定