【问题标题】:How to ensure parallel processing in JavaJava如何保证并行处理
【发布时间】:2016-07-26 03:52:16
【问题描述】:

我有一个静态数组arr,它的元素被平方并使用“平方”方法再次存储回来。我希望两个线程同时修改数组。每个线程在数组的一半上工作。

public class SimplerMultiExample {

    private static int[] arr = new int[10];
    public static void squarring(int start, int end)
    {
        for(int i=start; i<end; i++)
        {
            arr[i]*=arr[i];
            System.out.println("here "+Thread.currentThread().getName());
        }
    }


    private static Runnable doubleRun = new Runnable() {
        @Override
        public void run() {
        if(Integer.parseInt(Thread.currentThread().getName())==1)
            squarring(0,arr.length/2);  //Thread named "1" is operaing on
                                        //the 1st half of the array.
        else
            squarring(arr.length/2,arr.length);
        }
     };

    public static void main(String[] args){

         Thread doubleOne = new Thread(doubleRun);
         doubleOne.setName("1");

         Thread doubleTwo = new Thread(doubleRun);
         doubleTwo.setName("2");

         doubleOne.start();
         doubleTwo.start();
    }
}

'squarring' 方法中的 sysout 告诉我线程正在串行进入该方法,也就是说,一个线程在另一个线程访问它之前完成。结果,其中一个线程提前完成,而其他线程需要更长的时间才能完成。我已经用 100 万个元素测试了代码。请就我能做些什么以确保线程并行运行提出建议。 P.S - 我使用的是双核系统。

【问题讨论】:

  • 没有足够的工作让两个线程有​​意义地重叠。每个线程将需要一微秒左右的时间来执行。尝试将数组大小从 10 更改为 1,000,000,并在 main 方法的末尾添加 join() 调用。
  • @JimGarrison:OP 已经提到他已经“[...] 用 100 万个元素测试了代码”。
  • 不是答案,但是,如果您的 run() 方法不必检查线程名称来决定要处理数组的哪个部分,那么您的代码会更清晰。通常,如果你想让不同的线程做不同的事情,那么你应该给它们不同的Runnable 实例。在你的情况下,我会让它们成为同一个类的不同实例,我会创建 startend 构造函数参数。

标签: java multithreading performance


【解决方案1】:

您不必从头开始编程:

Arrays.parallelSetAll(arr, x -> x * x);

parallelSetAll 创建一个 parallel stream,它会为您完成所有工作:

使用提供的生成器函数并行设置指定数组的所有元素来计算每个元素。

如果您想知道如何控制用于并行处理的线程数,请查看this question

【讨论】:

  • @beatnu13,我确实用随机数填充了数组中的元素,但该方法与手头的问题无关,因此没有发布。感谢并行流上的 sn-p。会查的。
  • @TheGovernment:好的,不知道。我删除了评论。
【解决方案2】:

我建议您将以下代码添加到 main 方法的末尾,以确保它们各自完成工作:

     try {
        doubleOne.join(); //Waits for this thread to die. 

        doubleTwo.join(); //Waits for this thread to die. 
     } catch (InterruptedException e) {
        e.printStackTrace();
    }

正在创建两个可以并行执行的线程,前提是调度程序选择将它们交错。但是,调度程序不能保证交错执行。您的代码在我的系统上并行工作(......有时......但其他时候,线程串联执行)。

由于您不等待线程完成(使用join 方法),因此您不太可能观察到交错(因为您只观察程序执行的一部分)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 2021-05-08
    相关资源
    最近更新 更多