使用Java Semaphore时仅单个线程执行的问题排查
问题原因分析
你的核心错误是在主线程中提前调用了Semaphore.acquireUninterruptibly(),而非在线程内部的执行逻辑中调用。
具体逻辑矛盾点:
- 你设置Semaphore许可数为1,主线程遍历文件夹时,先调用
acquireUninterruptibly()拿到唯一许可,再启动第一个线程。 - 主线程接着遍历下一个文件夹,再次尝试调用
acquireUninterruptibly(),但此时许可已被主线程占用,主线程会直接阻塞在这里,根本无法创建并启动后续线程。 - 哪怕第一个线程执行完毕调用
release()释放许可,主线程也只会卡在第二次acquire的位置,拿到许可后才会创建第二个线程,接着又卡在第三次acquire——你误以为是后续线程不启动,本质是主线程被自己的acquire操作卡死了。
修正方案
把acquire和release的调用移到线程的run()方法内部,让每个线程自己申请和释放许可:
Semaphore semaphore = new Semaphore(1); // 主线程仅负责创建并启动线程,不调用acquire for (File folder : folderList) { new Thread(() -> { semaphore.acquireUninterruptibly(); // 线程内部获取许可 try { // 你的业务逻辑:执行命令、处理弹窗、重试逻辑等 } finally { semaphore.release(); // 确保无论成功失败都释放许可 } }).start(); }
这样主线程可以一次性创建并启动所有线程,所有线程会在自身执行逻辑开始前尝试获取Semaphore许可,许可数为1时,它们会自动排队依次执行,完全符合你的预期。
内容的提问来源于stack exchange,提问作者davidalayachew
相关产品推荐
相关产品推荐

