【问题标题】:Multithreading in Java findin prime number takes more time?Java中的多线程查找素数需要更多时间?
【发布时间】:2020-03-18 12:18:12
【问题描述】:

我试图找出这个问题的解决方案,但在 StackOverflow 上找不到?

我只是想知道为什么我的多线程工作如此缓慢,事实上它应该做得相反。

public class Prime {

    static BufferedWriter writer;
    static DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    public static void main(String[] args) throws IOException {


        System.out.println("Without Thread" + findPrime() + " ms");

        System.out.println("With thread : " + findPrimeWithThreads() + " ms");

    }

    public static long findPrimeWithThreads() {

        Instant start = Instant.now();

        int primaryNumber = 3;
        while (primaryNumber <= 100000) {

            int finalPrimaryNumber = primaryNumber;

            new Thread(() -> {
                multiplicationHelper(finalPrimaryNumber);
            }).start();

            new Thread(() -> {
                multiplicationHelper(finalPrimaryNumber+1);
            }).start();

            primaryNumber+=2;
        }

        return Duration.between(start, Instant.now()).toMillis();

    }

    public static long findPrime() throws IOException {
        Instant instant = Instant.now();

        int primaryNumber = 3;
        while (primaryNumber <= 100000) {

            multiplicationHelper(primaryNumber);

            primaryNumber++;

        }

        return Duration.between(instant, Instant.now()).toMillis();
    }

    public static void multiplicationHelper(int primaryNumber){
        int j = 2;
        boolean isPrime = true;

        while (j <= primaryNumber/2) {
            if (primaryNumber % j == 0) {
                isPrime = false;
                break;
            }
            j++;
        }
        if (isPrime) {
//            System.out.println("PRIME :: " + primaryNumber);
        }
    }

}

这是代码,代码的输出是:

Without Thread497 ms
With thread : 22592 ms

请您详细说明为什么会这样以及如何提高多线程的性能? 我是多线程编程的新手,所以我在这方面做错了吗?

【问题讨论】:

  • 不要在每次迭代时都启动新线程!
  • 创建一个新线程比执行操作本身花费的时间更长。您应该创建一个线程池并重用这些线程。或者,您可以创建几个线程并为它们分配部分工作负载。
  • Java 中的多线程新手?您需要快速了解这个 Java 教程主题:Concurrency

标签: java multithreading primes


【解决方案1】:

“寻找素数”是一个计算绑定操作。它自然会使用 100% 的 CPU 利用率,因为它永远不需要执行 I/O。

“多线程”的两个目的是:(a) 利用多个 CPU 内核,以及 (b) 与 I/O 重叠计算。 (并且更容易发出并行 I/O 操作。)

多线程可以在正确的情况下节省时间,在错误的情况下会花费更多的时间。

您考虑不周的设计似乎启动了 20,000 个线程!

【讨论】:

  • 这个“答案”暗示了这个问题(“你的设计考虑得很糟糕......”)但它实际上并没有回答 OP的问题。
【解决方案2】:

将您的功能更改为以下

public static long findPrimeWithThreads() {

        Instant start = Instant.now();

        int primaryNumber = 3;
        ExecutorService pool = Executors.newFixedThreadPool(4); // considering you've 4 CPU
        while (primaryNumber <= 100000) {
            int finalPrimaryNumber = primaryNumber;
            pool.submit(()->multiplicationHelper(finalPrimaryNumber));
            primaryNumber ++;
        }
        pool.shutdown(); // stop your threads
        return Duration.between(start, Instant.now()).toMillis();

    }

【讨论】:

  • 提交 100000 个任务效率不高(您正在创建 100000 个对象)。您应该只创建 4 个线程,每个线程探索四分之一的搜索范围。
  • 简单地向 OP 展示一个运行得更好的代码 sn-p(但在这种情况下,仍然远非最佳)与解释 OP 做错了什么不同。没有回答 OP 的问题,“为什么我的 [示例] 工作这么慢?”
猜你喜欢
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多