java - 什么是好的并行程序[使用 Java 线程]?

标签 java multithreading parallel-processing

我正在学习 Java 中的线程,以便创建一些并行运行的程序。并行设计程序是我在学校编程课上从未有机会学到的东西。我知道如何创建线程并使它们运行,但我不知道如何有效地使用它们。毕竟我知道,实际上并不是使用线程使程序变得更快,而是良好的并行设计。所以我做了一些实验来测试我的知识。然而,我的并行版本实际上比无与伦比的版本运行得慢。我开始怀疑我是否真的明白了这个想法。如果您能如此友善,您介意看看我的以下程序吗:

我编写了一个程序以分而治之的方式填充数组(我知道Java有一个Arrays.fill实用程序,但我只是想测试我在多线程方面的知识):

public class ParalledFill
{
    private static fill(final double [] array, 
                        final double value, 
                        final int start, 
                        final int size)
    {
        if (size > 1000) 
        { // Each thread handles at most 1000 elements
            Runnable task = new Runnable() { // Fork the task
                public void run() { 
                    fill(array, value, start, 1000); // Fill the first 1000 elements
            }};
            // Create the thread
            Thread fork = new Thread(task);
            fork.start(); 
            // Fill the rest of the array
            fill(array, value, start+1000, size-1000);
            // Join the task
            try {
                fork.join();
            }
            catch (InterruptedException except)
            {
                System.err.println(except);
            }
        }
        else 
        { // The array is small enough, fill it via a normal loop
            for (int i = start; i < size; ++i)
            array[i] = value;
        }
    } // fill

    public static void main(String [] args)
    {
        double [] bigArray = new double[1000*1000];
        double value = 3;
        fill(bigArray, value, 0, bigArray.length);
    }
}

我测试了这个程序,但事实证明它比仅仅执行以下操作还要慢:

for (int i = 0; i < bigArray.length; ++i)
    bigArray[i] = value;

我有我的猜测,可能是java对使用循环填充数组进行了一些优化,这使得它比我的线程版本快得多。但除此之外,我更强烈地感觉到我处理线程/并行性的方式可能是错误的。我从未使用线程设计过任何东西(总是依赖于编译器优化或 C 语言中的 OpenMP)。谁能帮我解释为什么我的并行版本不更快?该程序在设计并行程序方面是否太糟糕了?

谢谢, 兴。

最佳答案

除非您有多个 CPU,或需要长时间运行的任务(例如 I/O),否则我猜您所做的只是在线程之间进行时间切片。如果单个 CPU 有大量工作要做,那么添加线程并不会减少必须完成的工作。您最终所做的只是由于上下文切换而增加了开销。

您应该阅读“Java 并发实践”。更好地学习如何使用现代并发包而不是原始线程来完成任务。

关于java - 什么是好的并行程序[使用 Java 线程]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19734817/

相关文章:

performance - CyclicDist 在多个语言环境中变慢

java - 构建 ionic 应用程序时出现 "Your JAVA_HOME is invalid: C:\Program Files\Java\jdk1.8.0_301"

javascript - 正则表达式通过 html 标签和普通字符串中的空格分隔字符串

multithreading - Perl 使用线程的并行请求

android - android runOnUiThread和java中简单代码的区别

c - 如何组合/杀死 fork()

java - 防止更新时在 Mapstruct 中进行空检查

java - 在编译时访问VM参数

c++ - 来自 boost asio io_service get_service() 的错误指针

python - 如何基于机器学习模型并行化交易策略的回测?