计算1-x内的素数, 使用y个线程计算

计算1-x内的素数, 结果保存在mysql中
要求:
1. 使用y个线程计算
2. 尽量优化算法
3. x和y可配置
我是用的mvc写的
下面是线程池和素数计算方式
写到这里写不下去了,求帮助

package com.lsszss;

import com.lsszss.service.Impl.PrimeImpl;
import com.lsszss.service.PrimeService;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**

  • @ClassName Threads
  • @Author 25788
  • @Date 2019/12/20 11:52
  • @Version V1.0
  • java.util.concurrent.Executors :线程池的工厂类,用来生成线程池
  • 01.使用线程池的工厂类Executros里边提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池
  • 02.创建一个类,实现Runnable接口,重写run方法,设置线程任务
  • 03.调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
  • 04.调用ExecutorService中的方法shutdown销毁线程池(不建议使用)
    */
    public class prime {

    static PrimeService primeService= new PrimeImpl();

    private static List getPrimeNumber(int num){
    List arrayList = new ArrayList<>();
    for (int i = 1;i < num+1 ; i++){
    if (isPrime(i)){
    arrayList.add(i);
    primeService.addPrime(Long.parseLong(i+""));
    }
    }
    return arrayList;
    }

    public static boolean isPrime(int n){
    if (n==2||n==3){
    return true;
    }
    if (n%2==0){ // 是偶数就一定不是素数
    return false;
    }

    for (int i=3;i<=(int)Math.sqrt(n);i=i+2){ // 奇数+1为偶数,所以每次循环+2
        if (n%i==0) {return false;}
    }
    return true;
    

    }

    public static void main(String[] args) {
    int x=100; //1 - x 之间的素数
    int y=2; //线程数

    System.out.println(getPrimeNumber(x));
    // 01.使用线程池的工厂类Executros里边提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池
    ExecutorService executor = Executors.newFixedThreadPool(y);
    // 03.调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
    
    executor.submit(new PrimeThread());
    executor.submit(new PrimeThread());
    executor.submit(new PrimeThread());
    executor.submit(new PrimeThread());
    executor.submit(new PrimeThread());
    

    }
    }

2个回答

时间有限,提供一个思路吧。
首先,抽象一个素数求解任务;

import java.util.concurrent.CountDownLatch;

public class CheckPrimeTask implements Runnable{

    //需要校验的数,判断该数是否是素数
    private int number;

    //锁,控制任务总数
    private CountDownLatch latch;

    public CheckPrimeTask(int number,CountDownLatch latch) {
        this.number = number;
        this.latch = latch;
    }

    @Override
    public void run() {
        if(isPrime(this.number)) {
            //TODO 插入数据库
            System.out.println(Thread.currentThread()+"计算"+this.number+"是素数,已入库");
        }else {
            System.out.println(Thread.currentThread()+"计算"+this.number+"不是素数");
        }

        //计数器减少一
        this.latch.countDown();
    }

    public boolean isPrime(int n) {
        if (n == 2 || n == 3) {
            return true;
        }
        if (n % 2 == 0) { // 是偶数就一定不是素数
            return false;
        }
        for (int i = 3; i <= (int) Math.sqrt(n); i = i + 2) { // 奇数+1为偶数,所以每次循环+2
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
}

其次,定义测试类,循环向线程池提交 1-x 个求解素数的任务;

import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestPrimeByThreadPool {
    public static void main(String[] args) {
        int poolCount = 0;
        int primeScope = 0;
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入一个大于 2 的整数 x,需要计算的素数的范围");
        primeScope = scanner.nextInt();
        while(primeScope<2) {
            System.out.println("请输入一个大于 2 的整数 x,需要计算的素数的范围");
            primeScope = scanner.nextInt();
        }

        System.out.println("请输入一个整数 y,它控制线程池中工作线程的个数");
        poolCount = scanner.nextInt();
        while(poolCount<0) {
            System.out.println("请输入一个整数,它控制线程池中工作线程的个数");
            poolCount = scanner.nextInt();
        }

        scanner.close();

        //开启计算模式
        calculate(poolCount,primeScope);
    }

    private static void calculate(int poolCount,int primeScope) {
        //开启一个线程池
        ExecutorService pool = Executors.newFixedThreadPool(poolCount);

        //创建一个计数器锁
        CountDownLatch latch = new CountDownLatch(primeScope);

        //循环提交 N 个任务
        for(int i=1;i<=primeScope;i++) {
            pool.submit(new CheckPrimeTask(i,latch));
        }

        //等待计数器完成
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //关闭线程池
        pool.shutdown();
        System.out.println("统计完成,关闭线程池");
    }
}

运行结果:

请输入一个大于 2 的整数 x,需要计算的素数的范围
10
请输入一个整数 y,它控制线程池中工作线程的个数
3
Thread[pool-1-thread-3,5,main]计算3是素数,已入库
Thread[pool-1-thread-2,5,main]计算2是素数,已入库
Thread[pool-1-thread-1,5,main]计算1是素数,已入库
Thread[pool-1-thread-2,5,main]计算5是素数,已入库
Thread[pool-1-thread-1,5,main]计算4不是素数
Thread[pool-1-thread-2,5,main]计算6不是素数
Thread[pool-1-thread-2,5,main]计算8不是素数
Thread[pool-1-thread-1,5,main]计算7是素数,已入库
Thread[pool-1-thread-1,5,main]计算10不是素数
Thread[pool-1-thread-2,5,main]计算9不是素数

本人最近正在整理多线程编程的知识专栏,有兴趣可以去看看哦!祝好。

Allen_OI
Allen_OI 嗯,非常有用,谢谢大牛
2 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问