繁体   English   中英

如何将Math工作拆分为工作线程Java

[英]How to split Math work into worker threads Java

我正在开发一个Java应用程序,可以计算幂次。 我想利用我的四核计算机,因为此应用程序仅使用一个核。 我看过有关如何同步线程的不同教程,但我确实不明白。 我的代码如下:

public class Bignum{

public static void main(String[] args){

    Random generator = new Random();   
    long start = System.nanoTime();   
    Random generator1 = new Random();

for (long i=0; i<9000;i++){

    int power = generator1.nextInt (17) + 2;
    int power1 = generator1.nextInt (25) + 2;
    int power2 = generator1.nextInt (72) + 2;

    BigInteger num = BigInteger.valueOf (generator.nextInt (7895) + 1);
    BigInteger num1 = BigInteger.valueOf (generator.nextInt (1250) + 1);
    BigInteger num2 = BigInteger.valueOf (generator.nextInt (9765) + 1);

    BigInteger add = num.pow(power);
    BigInteger add1 = num1.pow(power1);
    BigInteger add2 = num2.pow(power2);

    BigInteger sum = add.add(add1);

}

}
}

因此,例如,如何让一个线程执行此操作:

    int power = generator1.nextInt (17) + 2;
    int power1 = generator1.nextInt (25) + 2;
    int power2 = generator1.nextInt (72) + 2;

另一个这样做:

    BigInteger num = BigInteger.valueOf (generator.nextInt (7895) + 1);
    BigInteger num1 = BigInteger.valueOf (generator.nextInt (1250) + 1);
    BigInteger num2 = BigInteger.valueOf (generator.nextInt (9765) + 1);

另一个:

    BigInteger add = num.pow(power);
    BigInteger add1 = num1.pow(power1);
    BigInteger add2 = num2.pow(power2);

最后一个是这样做的:

    BigInteger sum = add.add(add1);

我该怎么办? 另外,我怎么还能重复9000次? 谢谢您的帮助。

在Java 8中,并行数学可能非常优雅。 下面的代码利用了“ +”运算是加法运算的事实,因此可以按任意顺序对值进行求和。

因此,下面的代码并行创建一个数字序列,并在单个线程中减少(加和)它们。

import java.math.BigInteger;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.IntStream;

import static java.math.BigInteger.valueOf;
import static java.util.concurrent.ThreadLocalRandom.current;

public class Bignum {
    public static void main(String[] args) {
        Optional<BigInteger> sum = IntStream.range(0, 9000)
            .parallel()       <-- this enables parallel execution
            .mapToObj(value -> {
                ThreadLocalRandom generator = current();

                int power = generator.nextInt(17) + 2;
                int power1 = generator.nextInt(25) + 2;
                int power2 = generator.nextInt(72) + 2;

                BigInteger num = valueOf(generator.nextInt(7895) + 1);
                BigInteger num1 = valueOf(generator.nextInt(1250) + 1);
                BigInteger num2 = valueOf(generator.nextInt(9765) + 1);

                BigInteger add = num.pow(power);
                BigInteger add1 = num1.pow(power1);
                BigInteger add2 = num2.pow(power2);

                return add.add(add1).add(add2);
            })
            .reduce(BigInteger::add);

        System.out.println(sum.get());
    }
}

因此,我真的推荐这本书开始使用Java多线程。 就像这本书的圣经。

话虽这么说,您将需要一个线程池来保存您的任务,并且您需要创建一个“工人”类(将成为线程)来处理需要执行的操作,并正确地退出/返回它的价值。

-使您的线程池

ExecutorService executor = Executors.newFixedThreadPool(MAX_NUMBER_THREADS_AT_ONCE);

-完成您的工作任务

public static class WorkerTask implements Runnable {
    //member vars if you need em

    WorkerTask() {
        //initialize member vars if you need to
    }

    @Override
    public void run() {
            //do your work here 
    }
}

-将任务添加到线程池中,如下所示:

for( each task you need ){
        Runnable worker = new WorkerTask( constructor params );
        executor.execute(worker);
    }

最后,这留下两个问题:

我要如何等待他们完成?

如何从线程返回值?

事实是,这两个问题都有很多方法可以解决您的问题,但是我认为在这种情况下,您可以做一些简单的事情。 我建议使用一个全局静态变量,该变量将具有全局作用域,并且可以被所有线程访问。 在这里要小心,不要编辑与其他线程相同的值,因此请使用类似ConcurrentHashMap的名称,并且当一个线程有了答案时,只需将线程ID及其答案添加到哈希图中即可。 例如:parallelMap.add(threadId,value);

为了等待所有任务完成,我通常会执行以下操作:

executor.shutdown();  //signal that you want to shutdown executor
while(!executor.isTerminated()){
        Thread.sleep(10000);  //wait ten seconds
        System.out.println("Waiting 10 seconds");
}
// now finally traverse your value map and output your answers

我更喜欢使用队列进行线程输入和输出,请参阅文档中的示例: http : //download.java.net/jdk7/archive/b123/docs/api/java/util/concurrent/BlockingQueue.html

通常,有2.5个使用线程开头的原因:

  1. 在多CP​​U系统中
  2. 处理IO(监视器,鼠标,键盘,套接字,读/写文件等)时
  3. 计时器

假设您不执行IO且不需要计时器,那么线程数多于系统CPU的速度将降低您的速度。

暂无
暂无

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

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