Java 使用多线程在数组中查找素数

Java 使用多线程在数组中查找素数,java,arrays,multithreading,algorithm,parallel-processing,Java,Arrays,Multithreading,Algorithm,Parallel Processing,我目前正试图修改一个我工作过的顺序prime程序,并将其合并到多线程中。我想指定分割工作的线程数量,然后让每个线程运行一个算法来查找素数,然后显示每个线程中有多少素数 问题似乎是每个线程都在整个数组上运行算法,而不是在我指定的所需线程中拆分数组。我尝试了一些其他的东西,但它们几乎只是导致了更多的错误 现在,我正在对1000个数字的数组进行实验。一旦我让它工作,我会在数组中放入数百万个数字,但我只想先做更少的数字。1000的数组中应该有168个素数。问题是每个线程返回168个素数,这让我相信每个线

我目前正试图修改一个我工作过的顺序prime程序,并将其合并到多线程中。我想指定分割工作的线程数量,然后让每个线程运行一个算法来查找素数,然后显示每个线程中有多少素数

问题似乎是每个线程都在整个数组上运行算法,而不是在我指定的所需线程中拆分数组。我尝试了一些其他的东西,但它们几乎只是导致了更多的错误

现在,我正在对1000个数字的数组进行实验。一旦我让它工作,我会在数组中放入数百万个数字,但我只想先做更少的数字。1000的数组中应该有168个素数。问题是每个线程返回168个素数,这让我相信每个线程都在做相同的事情,而不是分割工作。我的问题是,我如何使用这个程序,让它拆分数组并以这种方式运行算法?因此,0到499将运行算法并显示线程0中的素数数量,然后500到1000将运行alg并显示该线程中有多少素数

这是我的代码-Prime.java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Prime extends Thread {


    Scanner scan = new Scanner(System.in);

    static long [] primes = new long [1000];
    static ArrayList<Integer> primeList = new ArrayList<Integer>();


      //int max = num;
   public int count = 0;


   public void run() {
        for (int n = 2; n<=primes.length; n++) {
              boolean prime = true;
                  for (int j = 2; j < n; j++) {
                          if (n%j == 0){
                              prime = false;
                              break;
                                }
                  }

                if (prime){
                        count++;
                        primeList.add(n);

                }

          }
   }
}
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Prime extends Thread {
    public int count = 0;
    public int lowerBound;
    public List<Integer> primeList = new ArrayList<>();

    public void run() {
        for (int n = lowerBound; n <= lowerBound+1000; n++) {
            BigInteger bi = BigInteger.valueOf(n);
            if (bi.isProbablePrime(100)){
                count++;
                primeList.add(n);
            }
        }
    }
}
import java.util.ArrayList;
导入java.util.List;
导入java.util.Scanner;
公共类素数扩展线程{
扫描仪扫描=新扫描仪(System.in);
静态长[]素数=新长[1000];
静态ArrayList primeList=新ArrayList();
//int max=num;
公共整数计数=0;
公开募捐{

对于(int n=2;n,据我所知,您有一个整数数组
[a1,a2,…,an]
,您希望找到这些整数中的哪些是素数

您希望通过为每个线程提供这些整数的一些子集来进行验证


如果是这样的话,那么你就错了。只要找到数组中元素的最大值,你就会快得多。然后运行以获得小于最大值的所有素数(注意,你不需要除以所有整数,只要小于
sqrt(n)
,因为最大的素数可以是
sqrt(n)

然后再运行一次数组,检查你的答案是否在素数图中

p.S.如果你想将许多数字分解,类似的想法也适用



如果您想学习如何在Java中执行线程,那么这并不是您想要的答案。

问题是每个线程都在循环所有值
for(int n=2;n我采用了另一种没有线程阻塞的方法。这可能的原因是
biginger.isProbablePrime()
。下面是代码:

Prime.java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Prime extends Thread {


    Scanner scan = new Scanner(System.in);

    static long [] primes = new long [1000];
    static ArrayList<Integer> primeList = new ArrayList<Integer>();


      //int max = num;
   public int count = 0;


   public void run() {
        for (int n = 2; n<=primes.length; n++) {
              boolean prime = true;
                  for (int j = 2; j < n; j++) {
                          if (n%j == 0){
                              prime = false;
                              break;
                                }
                  }

                if (prime){
                        count++;
                        primeList.add(n);

                }

          }
   }
}
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Prime extends Thread {
    public int count = 0;
    public int lowerBound;
    public List<Integer> primeList = new ArrayList<>();

    public void run() {
        for (int n = lowerBound; n <= lowerBound+1000; n++) {
            BigInteger bi = BigInteger.valueOf(n);
            if (bi.isProbablePrime(100)){
                count++;
                primeList.add(n);
            }
        }
    }
}

你的观点是什么?你是想在数组中高效地找到素数,还是想学习如何用java制作线程?@Salvadodali。显然不是第一个。对不起,我投票决定结束这个问题。我理解这个问题的答案,但这是一个关于编写线程安全代码和如何在Java。你需要在别处找到答案。只需根据元素总数和线程数计算一组开始和结束索引。给每个线程一个索引来划分工作。@Salvadodali用Java生成线程。但我应该在一个数百万个数字的数组上使用多线程,然后输出素数。在我们之间,我们已经讨论了这两个方面。无论哪种方式都需要教程。很高兴你解决了与线程+1相关的部分问题。是的,我认为这比我脑死亡时的埃拉托什尼筛子更容易解释:)另外,这似乎是OP最不了解的事情。解释筛子做得很好。你应该提到,你只需要检查
n
的平方根。顺便说一句,谢谢,疯狂科学家。我用你的建议调整了代码。每个线程的输出仍然是168和168。这可能是一个连接问题吗?我意识到我的代码有问题。我不是一个好的程序员,我花了几天的时间才发现它的缺陷。我希望我至少接近它。我没有做线程的业务,但我必须给它分配任务即使对我来说,抛开名字不谈,你也应该在之前(或者至少在一段时间内)看看基本的Oracle教程潜入:。它真的很好,可能足以满足您要做的事情。而且,它不应该花那么长时间阅读。@user3577397我已经尝试了上面提到的答案,它工作正常。我在主构造函数中只发现了一个键入错误。它应该是
int end
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Prime extends Thread {
    public int count = 0;
    public int lowerBound;
    public List<Integer> primeList = new ArrayList<>();

    public void run() {
        for (int n = lowerBound; n <= lowerBound+1000; n++) {
            BigInteger bi = BigInteger.valueOf(n);
            if (bi.isProbablePrime(100)){
                count++;
                primeList.add(n);
            }
        }
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Worker {
    public static void main(String[] args) {
         Scanner scan = new Scanner(System.in);
         System.out.println("How Many threads? ");
         int nThreads = scan.nextInt();  // Create variable 'n'  to handle whatever integer the user specifies.  nextInt() is used for the scanner to expect and Int.

         final Prime[] pThreads = new Prime[nThreads];
         long startTime = System.currentTimeMillis();
         for(int i = 0; i<nThreads; i++){
             pThreads[i] = new Prime();
             pThreads[i].lowerBound = 2+1000*i;
             pThreads[i].start();
         }

         try {
             for (int i = 0; i < nThreads; i++)
                 pThreads[i].join();
         } catch (InterruptedException e) {
         }
         long stopTime = System.currentTimeMillis();
         long elapsedTime = stopTime - startTime;
         System.out.println("Execution time = : "+  elapsedTime);
         System.out.println("----------------------------------------------------");
         int cores = Runtime.getRuntime().availableProcessors();
         System.out.println("How many Cores this Java Program used: " + cores);
         for (int i = 0; i < nThreads; i++)
             System.out.println("Thread " + i + "  Prime count: " + pThreads[i].count); // Display Thread count
         List<Integer> allPrimes = new ArrayList<>();
         for (Prime p : pThreads) {
             allPrimes.addAll(p.primeList);
         }
         System.out.println("Total prime count: " + allPrimes.size()); // Output total amount of primes from the Array List
         for (int i = 0; i < 100; i++) // Display first 100 primes.
             System.out.println(allPrimes.get(i));
     }
 }
How Many threads?
2
Execution time = : 35
How many Cores this Java Program used: 12
Thread 0  Prime count: 168
Thread 1  Prime count: 135
Total prime count: 303
...