简体   繁体   English

什么是具有Java线程的良好并行程序?

[英]What is a good parallel program [with Java Thread]?

I am learning Thread-ing in Java in order to create some program run in parallel. 我正在学习Java中的线程处理,以创建一些并行运行的程序。 To design programs with parallelism is something I never had a chance to learn back at my school programming class. 设计具有并行性的程序是我从来没有机会在学校编程课上学习的东西。 I know how to create threads and make them run, but I have no idea how to use them efficiently. 我知道如何创建线程并使它们运行,但是我不知道如何有效地使用它们。 After all I know it is not actually using threads that makes a program fast but a good parallel design. 毕竟,我知道实际上并没有使用使程序快速运行的线程,而是一种不错的并行设计。 So I did some experiment to test my knowledge. 所以我做了一些实验来测试我的知识。 However, my paralleled version actually runs slower than an unparalleled one. 但是,我的并行版本实际运行速度比无并行版本慢。 I start to doubt if I really get the idea. 我开始怀疑我是否真的明白。 If you could be so kind, would you mind having a look my following program: 如果您如此友善,可以介意看看我的以下程序:

I made a program to fill an array in a divide-and-conquer fashion (I know Java has a Arrays.fill utility, but I just want to test my knowledge in multithreading): 我编写了一个程序来以分而治之的方式填充数组(我知道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);
    }
}

I tested this program, but it turns out to be even slower than just doing something like: 我测试了该程序,但结果比做类似的事情还要慢:

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

I had my guess, it could be that java does some optimisation for filling an array using a loop which makes it much faster than my threaded version. 我有一个猜测,可能是java对使用循环填充数组进行了一些优化,使其比我的线程版本快得多。 But other than that, I feel more strongly that my way to handle threads/parallelism could be wrong. 但是除此之外,我更强烈地感觉到我处理线程/并行性的方式可能是错误的。 I have never designed anything using threads (always relied on compiler optimisation or OpenMP in C). 我从未使用线程设计任何东西(始终依赖于编译器优化或C语言中的OpenMP)。 Could anyone help me explain why my paralleled version isn't faster? 谁能帮我解释一下为什么我的并行版本不快? Was the program just too bad in terms of designing paralleled program? 就设计并行程序而言,程序是否太糟糕了?

Thanks, Xing. 谢谢你邢

Unless you have multiple CPUs, or long running tasks like I/O, I'm guessing that all you're doing is time slicing between threads. 除非您有多个CPU或长时间运行的任务(例如I / O),否则我想您要做的就是线程之间的时间分割。 If there's a single CPU that has so much work to do, adding threads doesn't decrease the work that has to be done. 如果只有一个CPU有很多工作要做,那么添加线程并不会减少必须完成的工作。 All you end up doing is adding overhead due to context switching. 您最终要做的就是由于上下文切换而增加了开销。

You ought to read "Java Concurrency In Practice". 您应该阅读“ Java并发实践”。 Better to learn how to do things with the modern concurrency package rather than raw threads. 更好地学习如何使用现代并发包而不是原始线程来做事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM