对问题的解释: 您必须编写一个多线程程序来查找所有 范围[1,n]中可被3、5或7整除的整数.返回 所有唯一整数的总和作为您的答案. 请注意,像15这样的整数(3和5的倍数)仅为 数过一次. 正整数n>0作为输入提供给您.创建尽可能多的线程 你需要解决这个问题.您可以使用线程池获得加分.

Example:
Input: n = 10
Output: sum = 40
Explanation: Numbers in the range [1, 10] that are divisible by 3, 5, or 7 are:
3, 5, 6, 7, 9, 10. The sum of these numbers is 40.

我的解决方案和我面临的问题: 在这个程序中,我创建了三个线程,每个线程分别用于查找被3、5和7整除的整数,然后它将把它们全部存储在被除数数组列表中,并通过以下代码删除数组列表中的重复数:

Set<Integer> set = new HashSet<>(dividends);
    dividends.clear();
    dividends.addAll(set);

我使用了老师提供的一些测试用例,问题是在测试用例中,n=76293和n=1000不会显示预期的金额:

n=1000
expected sum:272066
actual sum:247377

另一个问题是,每次我运行测试用例时,实际金额都会不断变化. 有人能告诉我我的代码出了什么问题吗?我该如何修复它

我的代码是:

import java.util.*;
public class FindMultiples
{

public static ArrayList<Integer> dividends = new ArrayList<>();
public static int temp = 0;
public static synchronized void increment(){
    dividends.add(temp);
}
public static class thread implements Runnable{

    public int divisor;
    public int n;

    public thread(int n , int divisor){
        this.n=n;
        this.divisor=divisor;
    }

    @Override
    public void run() {

        for (int i=1 ; i<=n ; i++){
            if (i%divisor==0){
                temp=i;
                increment();
            }
        }
    }
}

public int getSum(int n) {
    int sum = 0;
    Thread thread1 = new Thread(new thread(n,3));
    Thread thread2 = new Thread(new thread(n,7));
    Thread thread3 = new Thread(new thread(n,5));
    
    thread3.start();
    thread2.start();
    thread1.start();
    try {
        thread3.join();
        thread2.join();
        thread1.join();
    }catch (InterruptedException e){

    }
    Set<Integer> set = new HashSet<>(dividends);
    dividends.clear();
    dividends.addAll(set);

    for (int i : dividends){
        sum+=i;
    }

    return sum;
}

public static void main(String[] args) {
}
}

推荐答案

您的主要问题很可能是正在同步增量()方法,而不是同步TEMP变量. 当一个线程试图执行increen()方法时,另一个线程正在更改temp变量的值.在DEBUG中运行您的代码并将其签出.

将值直接发送到Increen()比将其存储在temp中要好. 请参阅我编辑过的代码:

import java.util.*;
public class FindMultiples
{

public static ArrayList<Integer> dividends = new ArrayList<>();
public static synchronized void increment(int temp){
    dividends.add(temp);
}
public static class MyThread implements Runnable{

    public int divisor;
    public int n;

    public MyThread(int n , int divisor){
        this.n=n;
        this.divisor=divisor;
    }

    @Override
    public void run() {

        for (int i=1 ; i<=n ; i++){
            if (i%divisor==0){
                increment(i);
            }
        }
    }
}

public int getSum(int n) {
    int sum = 0;
    Thread thread1 = new Thread(new MyThread(n,3));
    Thread thread2 = new Thread(new MyThread(n,7));
    Thread thread3 = new Thread(new MyThread(n,5));

    thread3.start();
    thread2.start();
    thread1.start();
    try {
        thread3.join();
        thread2.join();
        thread1.join();
    }catch (InterruptedException e){
        System.out.println(e.getMessage());
    }
    Set<Integer> set = new HashSet<>(dividends);
    dividends.clear();
    dividends.addAll(set);

    for (int i : dividends){
        sum+=i;
    }

    return sum;
}

public static void main(String[] args) {
    FindMultiples findMultiples = new FindMultiples();
    System.out.println(findMultiples.getSum(1000));
}

}

Java相关问答推荐

如何用javac编译Java类,即使对像java.lang.*这样的基本类也没有任何依赖关系?

int Array Stream System. out. print方法在打印Java8时在末尾添加% sign

Java WireMock定义存根在Cucumber并行执行的多线程测试中失败

SQlite for Android无法使用json_group_array/json_object

如何配置ActiveMQ Artemis以使用AMQP 1.0和其他协议与Java

安装Java Jar应用程序的Install4j遇到ClassNotFoundException的运行时错误

返回响应时,CamelCase命名约定不起作用

如何使用Jackson将XML元素与值和属性一起封装

Java中将文本拆分为数字或十进制数字和字符串

GetChildren().emoveAll()不会删除 node

Java SSLKeyManager出厂密码

如何根据配置动态创建N个bean

无法使用Java PreparedStatement在SQLite中的日期之间获取结果

具有最大共同前景像素的图像平移优化算法

接受类及其接口的Java类型(矛盾)

JavaFX:为什么我的ComboBox添加了一个不必要的单元格的一部分?

Java 21内置http客户端固定运营商线程

如何在MPAndroidChart中的条形图上正确添加标签

java21预览未命名的符号用于try-with-resources

Maven创建带有特定类的Spring Boot jar和普通jar