Java 如何使用多个线程查找数字范围的总和?

Java 如何使用多个线程查找数字范围的总和?,java,multithreading,Java,Multithreading,系统应该以x线程数量计算一个数字范围的总和,其中用户输入数字范围和x线程数量 示例:如果范围为1-4,将在2个线程中计算: Thread 1: 1 + 2 = 3 Thread 2: 3 + 4 = 7 Total = 10 MyThread类只是我为更好地理解线程如何工作而编写的一个示例,而不是解决方案的实际尝试 MyThread类: class MyThread implements Runnable { private String name; MyThread(St

系统应该以x线程数量计算一个数字范围的总和,其中用户输入数字范围和x线程数量

示例:如果范围为1-4,将在2个线程中计算:

Thread 1: 1 + 2 = 3
Thread 2: 3 + 4 = 7

Total = 10
MyThread类只是我为更好地理解线程如何工作而编写的一个示例,而不是解决方案的实际尝试

MyThread类:

class MyThread implements Runnable {
    private String name;

    MyThread(String thread) {
        name = thread;
        System.out.println("Start: " + name);
        try { Thread.sleep(500); } catch (Exception e) { System.out.println(e); }
    }

    //countdown from 5 to 1 for each thread
    @Override
    public void run() {
        for (int i=5; i>0; i--){
            System.out.println(name + ": " + i);
            try { Thread.sleep(500); } catch (Exception e) { System.out.println(e); }
        }
        System.out.println(name + " Exiting");
    }
}
主要类别:

public class SimpleThreadExample {
    public static void main (String[] args) throws InterruptedException {
        Thread t = new Thread();

        //get number of threads from user
        System.out.print("Enter the number of threads: ");
        Scanner input = new Scanner(System.in);
        int number = input.nextInt();

        //create the threads
        for (int i=1; i<=number; i++) {
            t = new Thread(new MyThread("Thread " + i));
            t.start();
        }

        t.join();
        System.out.println("End");
    }
}
公共类SimpleThreadExample{
公共静态void main(字符串[]args)引发InterruptedException{
螺纹t=新螺纹();
//从用户获取线程数
System.out.print(“输入线程数:”);
扫描仪输入=新扫描仪(System.in);
int number=input.nextInt();
//创建线程

对于(inti=1;i,一种简单的Java-8方法是使用并行流

int[] numbers = {1,2,3,4,5,6,7,8,9,10};

int sum = Arrays.stream (numbers).parallel()
                        .sum ();
如果您需要通过手动创建线程来完成此操作,您可以围绕下面的行进行操作

    CountDownLatch countDownLatch = new CountDownLatch (2);

    SummationTask task1 = new SummationTask (countDownLatch,Arrays.copyOfRange (numbers, 0, numbers.length / 2));
    SummationTask task2 = new SummationTask (countDownLatch,Arrays.copyOfRange (numbers, (numbers.length / 2), numbers.length));
    Thread thread = new Thread (task1);
    Thread thread2 = new Thread (task2);
    thread.start ();
    thread2.start ();
    try {
        countDownLatch.await ();
        int totalSum = task1.sum + task2.sum;
        System.out.println ("sum => " + totalSum);
    } catch (InterruptedException e) {
        e.printStackTrace ();
    }
在SummationTask中,添加拆分数组元素

class SummationTask implements Runnable {

    CountDownLatch countDownLatch;
    int[] arr;
    int sum;

    public SummationTask(CountDownLatch countDownLatch, int[] arr) {
        this.countDownLatch = countDownLatch;
        this.arr = arr;
    }

    @Override
    public void run() {
        int sum = Arrays.stream (arr)
                .sum ();
        this.sum = sum;
        countDownLatch.countDown ();
    }
}

PS:上面的解决方案创建了2个线程,您可以通过使用所需大小的线程池(按间隔分割数组)和
可调用的
未来的
来改进这一点。如果您使用未来的

可以摆脱倒计时锁,一个简单的Java-8方法就是使用并行流

int[] numbers = {1,2,3,4,5,6,7,8,9,10};

int sum = Arrays.stream (numbers).parallel()
                        .sum ();
如果您需要通过手动创建线程来完成此操作,您可以围绕下面的行进行操作

    CountDownLatch countDownLatch = new CountDownLatch (2);

    SummationTask task1 = new SummationTask (countDownLatch,Arrays.copyOfRange (numbers, 0, numbers.length / 2));
    SummationTask task2 = new SummationTask (countDownLatch,Arrays.copyOfRange (numbers, (numbers.length / 2), numbers.length));
    Thread thread = new Thread (task1);
    Thread thread2 = new Thread (task2);
    thread.start ();
    thread2.start ();
    try {
        countDownLatch.await ();
        int totalSum = task1.sum + task2.sum;
        System.out.println ("sum => " + totalSum);
    } catch (InterruptedException e) {
        e.printStackTrace ();
    }
在SummationTask中,添加拆分数组元素

class SummationTask implements Runnable {

    CountDownLatch countDownLatch;
    int[] arr;
    int sum;

    public SummationTask(CountDownLatch countDownLatch, int[] arr) {
        this.countDownLatch = countDownLatch;
        this.arr = arr;
    }

    @Override
    public void run() {
        int sum = Arrays.stream (arr)
                .sum ();
        this.sum = sum;
        countDownLatch.countDown ();
    }
}

PS:上述解决方案创建了2个线程,您可以通过使用所需大小的线程池(按间隔拆分数组)来改进这一点和
Callable
Future
。如果您使用Future

Hi OJ,您可以将范围除以线程数,然后将每个子范围传递给一个线程。您可以使用MyThread构造函数传递子范围。在run方法中,您可以进行求和,并将结果存储在结果字段中同样在MyThread类中。然后在每个线程上调用join,等待它们“死亡”,在它们“死亡”之后您可以读取每个线程的结果并求和。我一定会尝试,这似乎是一个很好的解决方案。阅读Hi OJ,您可以将范围除以线程数,然后将每个子范围传递给一个线程。您可以使用MyThread构造函数传递子范围。在run方法中,您可以进行求和并将结果存储在结果中然后在每个线程上调用join,在线程“死”之后等待它们“死”您可以读取每个线程的结果并求和。我一定会尝试,这似乎是一个很好的解决方案。阅读此示例,是否可以动态创建线程而不是手动创建线程?因为似乎不可能在不手动输入公式的情况下将数字数组拆分为子范围。这是一个学术难题吗Igment?还是业务问题?如果是业务问题,我强烈建议您使用并行流。答案中描述的方法使用硬编码的线程数。此外,关于使用
parallel
:非常适合此任务的是
IntStream.rangeClosed(start,end).parallel().sum()
@Zgurskyi线程数是我知道的硬编码的,答案中也提到了它。@GovindaSakhare那么你的答案是不相关的,因为它明确提到,线程应该动态输入。另外,在你对Arrays.stream的建议中,你并没有实际控制要使用的线程数。可能吗在本例中,动态创建线程而不是手动创建线程?因为似乎不可能在不手动输入公式的情况下将数字数组拆分为子范围。这是某种学术作业吗?还是一个业务问题?如果是业务问题,我强烈建议您使用并行流。中描述的方法答案使用硬编码的线程数。另外,关于使用
parallel
:非常适合该任务的是
IntStream.rangeClosed(start,end).parallel().sum()
@Zgurskyi线程数是我知道的硬编码的,答案中也提到了它。@GovindaSakhare那么你的答案是不相关的,因为它明确提到,线程应该动态输入。另外,在你对Arrays.stream的建议中,你并没有实际控制要使用的线程数。