【问题标题】:Multithread loop which comparing two Strings比较两个字符串的多线程循环
【发布时间】:2021-01-12 11:14:34
【问题描述】:

我有练习学习多线程。我有一个正确的密码,例如:xxYYmmDD xx 是我的“员工”列表中的首字母,YY 是出生年份,mm 是出生月份,DD 是出生日期。例如:Nichole Hunter 09/10/93 密码为:NH930910。 但是这个循环只知道密码从首字母开始,之后有 6 个数字。 (稍后我必须用另一种方法创建其他循环,并比较哪种方法与多线程更快找到密码,但现在这并不重要)

我有一个在多线程中工作的循环,并且为每个初始添加一个从 000000 到 999999 的数字字符串并检查它是否等于正确的密码。 我不知道为什么永远不会调用“if”的指令。有人知道如何提供帮助吗? 如果我找到正确的密码,如何停止其他线程?

executorService= Executors.newFixedThreadPool(30);
        String finalCorrect = correct;

        for(String x : inicials){
            executorService.submit(()->{
            for(int count=0;count<999999; count++){
                
                if(finalCorrect.equals(x+String.format("%06d", count).trim())){
                    System.out.println("Correct password is: "+x+String.format("%06d", count).trim());
                    System.out.println("The really password is: "+ finalCorrect);
                    break;
                }
            }
                    }
            );

        }
        executorService.shutdown();
        try {
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException x) {
            System.out.println(x);
        }

【问题讨论】:

  • initials 中有什么内容?你能检查finalCorrect.startsWith(x) 是否返回 true 吗?
  • initials 是所有员工姓名首字母的列表。 finalCorrect.startsWith(x) 在整个循环中返回 false
  • 那是错误,如果finalCorrect 的两个初始字符不在列表initials 中,您将找不到它

标签: java multithreading for-loop if-statement


【解决方案1】:

代码基本上是正确的。问题似乎出在初始化参数中。如果以您的示例为例,正确的密码 (finalCorrect) 以 NH 开头,那么在列表 initials 中必须有值 NH

至于找到解决方案后停止工作线程,您可以调用executorService.shutdownNow() 尝试停止线程。在循环内部,您必须检查中断状态。

这是对您的代码的修改,带有更多的日志记录,它会停止工作线程:

    ExecutorService executorService= Executors.newFixedThreadPool(30);

    for(String x : inicials){
        System.out.println("Checking " + x);
        executorService.submit(()->{
                    for(int count=0;count<999999; count++){

                        if(finalCorrect.equals(x+String.format("%06d", count).trim())){
                            System.out.println("Correct password is: "+x+String.format("%06d", count).trim());
                            System.out.println("The really password is: "+ finalCorrect);
                            // Attempt to stop all the threads...
                            executorService.shutdownNow();
                            break;
                        }

                        // Test if the thread has been requested to stop
                        if (Thread.currentThread().isInterrupted()) {
                            System.out.println("Interrupted " + x);
                            return;
                        }
                    }
                    System.out.println("End " + x);
                }
        );

    }
    executorService.shutdown();
    try {
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    } catch (InterruptedException x) {
        System.out.println(x);
    }

使用 Java 8 的新 Streams 特性,您可以以更紧凑的形式实现相同的 aPproach:

    inicials.parallelStream()
            .flatMap(x -> IntStream.rangeClosed(0, 999999).mapToObj(i -> x + String.format("%06d", i)))
            .filter(finalCorrect::equals)
            .findAny()
            .ifPresent(x -> System.out.println("Found correct password: " + x));

【讨论】:

  • 那线程杀手工作得很好。我检查密码的循环不起作用,因为我的自动员工生成器(我从一些假名生成器网站下载数据并创建新的员工对象)但是当我自己创建一些员工对象并将其添加到列表时工作正常。我不知道为什么 Employe 生成器会破坏我的 if 语句...
猜你喜欢
  • 1970-01-01
  • 2013-06-06
  • 1970-01-01
  • 2018-05-23
  • 2020-05-17
  • 2017-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多