当前位置: 首页 > 知识库问答 >
问题:

什么是好的并行程序【用Java线程】?

温翔宇
2023-03-14

我正在学习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)。有人能帮我解释一下为什么我的并行版本没有更快吗?这个程序在设计并行程序方面是否太糟糕了?

谢谢,星。

共有1个答案

危文乐
2023-03-14

除非您有多个CPU,或者I/O等长时间运行的任务,否则我猜您所做的只是线程之间的时间切片。如果有一个CPU有这么多工作要做,添加线程不会减少必须完成的工作。由于上下文切换,您最终所做的只是增加开销。

你应该阅读“实践中的Java并发性”。最好学习如何使用现代并发包而不是原始线程来做事情。

 类似资料:
  • 问题内容: Java中的守护程序线程是什么? 问题答案: 守护程序线程是在程序完成但线程仍在运行时不会阻止JVM退出的线程。守护程序线程的一个示例是垃圾回收。 你可以使用该方法在线程启动之前更改守护程序属性。

  • 本文向大家介绍什么是Java中的守护程序线程?,包括了什么是Java中的守护程序线程?的使用技巧和注意事项,需要的朋友参考一下 Java中的守护程序线程是在后台连续执行的线程。您可以使用setDaemon()方法设置线程守护程序。 示例 输出结果

  • 问题内容: 我有一个程序,可以执行大量计算并经常将其报告到文件中。我知道频繁的写入操作会大大降低程序的速度,因此,为了避免出现这种情况,我希望有一个专门用于写入操作的线程。 现在,我正在用我写的这堂课(不耐烦的可以跳到问题的结尾): 然后我通过以下方式使用它: 尽管此方法运行良好,但我想知道: 是否有更好的方法来实现这一目标? 问题答案: 您的基本方法看起来不错。我将代码结构如下: 如果你不希望在

  • 主要内容:1 什么是Java多线程,2 Java多线程的优点,3 进程与线程区别,4 Java Thread类,5 Java Thread类的方法1 什么是Java多线程 Java 多线程指的是同时执行多个线程的处理。 线程是轻量级子进程,是最小的处理单元。多处理和多线程都用于实现多任务。 但是,我们使用多线程而不是多进程,因为线程使用共享内存区域。它们不分配单独的内存区域,因此节省了内存,并且线程之间的上下文切换比进程花费的时间更少。 线程是轻量级子进程,是最小的处理单元。这是一条单独的执行路

  • 到目前为止,我的印象是,在同一时间启动的两个线程也是并行执行的(两个线程都在同一时间运行它们的代码段),但我最近阅读了一些文档,我了解到它们实际上轮流执行它们的代码,因此第一个线程的代码段与第二个线程的代码段在同一时间执行是不存在的。我的理解正确吗? 如果是,那么多线程执行比单线程执行快多少?我这么问是因为唯一的区别是单线程顺序执行代码,而多线程可以轮流执行,但仍然需要相同的时间,因为它不是并行执

  • 问题内容: 是什么使线程的执行顺序不可预测?调度程序是在某个时候使用随机数还是检查系统资源,还是查看哪个线程已经等待了足够长的时间或…? 问题答案: 调度程序通常是OS的调度程序。它受许多因素的影响,包括计算机上的其他进程正在执行的操作,硬件在执行的操作(中断)等。根据操作系统的不同,我想有时可能涉及随机数,但我通常怀疑不是。多个可变时间间隔可能会重叠,这只是一种不可预测的方式。