Java多线程匹配密码时if条件不触发,找到正确密码后如何终止其他线程
匹配判断块不触发的核心原因
- 循环边界覆盖不全:现有循环条件为
count < 999999,count的取值范围为0~999998,仅能覆盖000000到999998的数字组合,遗漏了数字串为999999的匹配场景,总遍历组合数差1种,若正确密码的数字部分刚好为999999,会永远无法匹配。 - 字符串大小写不匹配:
String.equals()严格区分大小写,如果姓名首字母列表存储的是小写值(如nh),而正确密码的首字母为大写格式(如NH),判断条件永远不成立。 - 字符串长度不对齐:若正确密码的数字部分存在前导零遗漏(例如应匹配
930910但实际传入的correct值为93091,长度差1位),拼接后的字符串与正确密码长度不一致,无法匹配。 - 冗余操作干扰:原有代码对格式化后的数字串调用
.trim()属于无意义操作(%06d格式化生成的数字串无前后空格),虽不会直接导致匹配失败,但若后续逻辑调整引入额外空格,反而可能因字符处理错位触发匹配异常。
匹配成功后终止其他线程的实现方案
现有代码仅在当前线程匹配成功时执行break,只能退出自身的数字遍历循环,其余正在运行的线程无感知,仍会完成近100万次无效遍历。需通过线程安全的全局共享终止标志实现协作式退出:
- 引入
AtomicBoolean类型的全局标志位(初始值为false),利用原子类的线程可见性保证一个线程对标志的修改,所有其他线程可立即感知,避免普通布尔变量的可见性问题。 - 每个提交的遍历任务,在数字循环的开头增加标志位检查:若检测到标志位已被设置为
true(即其他线程已经匹配到正确密码),立即break退出当前循环,不再执行后续判断。 - 当某个线程在if块中匹配到正确密码时,第一步先将全局标志位设置为
true,再执行打印逻辑、退出当前循环,所有其他运行中的线程会在后续循环检查点检测到标志位变化,快速终止遍历。
Java不推荐强制中断或杀死正在运行的工作线程,协作式的标志位退出可以避免资源泄漏、数据不一致问题,是多线程任务终止的标准实现方式。
修正后的参考代码
ExecutorService executorService = Executors.newFixedThreadPool(30); String finalCorrect = correct; // 线程安全的全局匹配终止标志 AtomicBoolean passwordFound = new AtomicBoolean(false); for(String x : inicials){ executorService.submit(()->{ // 遍历覆盖全部100万种数字组合 for(int count=0; count < 1000000; count++){ // 提前检查是否已有其他线程匹配到结果 if(passwordFound.get()){ break; } String tryPassword = x + String.format("%06d", count); if(finalCorrect.equals(tryPassword)){ // 先设置全局终止标志,通知所有其他线程退出 passwordFound.set(true); System.out.println("Correct password is: " + tryPassword); System.out.println("The really password is: " + finalCorrect); break; } } }); } executorService.shutdown(); try { executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); } catch (InterruptedException e) { System.out.println(e); }
内容的提问来源于stack exchange,提问作者Patryk Chojnacki
相关产品推荐
相关产品推荐

