多线程质数检测程序出现死锁问题求助
First off, don't worry—thread synchronization trips up almost everyone starting out, so these are totally common mistakes. Let's break down why your code only outputs 2 and 3 then gets stuck, and how to fix it:
1. Your locks are totally useless (the big one)
Each NewThread instance creates its own Lock lock=new ReentrantLock();—that means every thread is holding a unique lock, so there's no actual synchronization happening when they access the shared counter variable. Multiple threads are clobbering counter at the same time, causing race conditions, and that's part of why things go haywire.
Fix: Make the lock a shared resource! Declare it as a static variable in Main so all threads use the same lock to protect access to counter.
2. Your prime-check logic is broken
Your isPrime method starts looping from i=1—but every integer is divisible by 1! So any number greater than 3 will immediately return false, which is why you only see 2 and 3 printed.
Fix: Start the loop at i=2, and adjust the loop condition to i <= (int)limit (since you need to check if the number is a perfect square, like 4=2*2). We can also add quick checks for even numbers to speed things up.
3. The increment method isn't thread-safe
The static counter variable is modified without any synchronization, so multiple threads can run ++counter at the same time, leading to duplicated or skipped numbers. Plus, the count=++counter; return counter; logic is redundant—you can just return ++counter directly, but only after making sure the operation is atomic.
Fix: Wrap the counter modification in the shared lock to ensure only one thread can update it at a time.
4. Exception handling causes an infinite loop
When counter hits 1e9, increment returns -1. Your isPrime method throws ThresholdReachedException for negative numbers, but your catch block just swallows the exception and lets the loop keep running. This means the thread will keep calling isPrime(-1), throwing the exception, catching it, and repeating forever—making it look like a deadlock (it's actually an infinite loop of exceptions).
Fix: When increment returns -1, break out of the loop to terminate the thread cleanly.
Fixed Full Code
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; // Don't forget to define your custom exception class! class ThresholdReachedException extends Exception { public ThresholdReachedException(String message) { super(message); } } public class Main { public static int counter = 0; // Shared lock for all threads to synchronize counter access public static final Lock sharedLock = new ReentrantLock(); public static void main(String[] args) { Thread[] threads = new Thread[10]; for (int i = 0; i < 10; i++) { threads[i] = new Thread(new NewThread()); threads[i].start(); } } public static int increment() { sharedLock.lock(); try { if (counter >= 1000000000) { return -1; } return ++counter; } finally { // Always unlock in finally to avoid lock leaks if something goes wrong sharedLock.unlock(); } } } class NewThread implements Runnable { public boolean isPrime(int number) throws ThresholdReachedException { if (number < 0) { throw new ThresholdReachedException("Limit Reached"); } if (number <= 1) { return false; } if (number == 2) { return true; // Quick exit for the only even prime } if (number % 2 == 0) { return false; // All other evens aren't primes } // Only check odd divisors up to sqrt(number) for efficiency double sqrtLimit = Math.sqrt(number); for (int i = 3; i <= (int) sqrtLimit; i += 2) { if (number % i == 0) { return false; } } return true; } @Override public void run() { try { while (true) { int number = Main.increment(); if (number == -1) { // Exit loop when we hit the counter limit System.out.println(Thread.currentThread().getName() + " exiting - counter limit reached"); break; } if (isPrime(number)) { System.out.println(Thread.currentThread().getName() + " Prime number : " + number); } } } catch (ThresholdReachedException e) { // Just in case the exception is thrown, log and exit System.out.println(Thread.currentThread().getName() + " stopped: " + e.getMessage()); } } }
Key Fix Recap
- Shared Lock: All threads use the same lock to safely modify the shared
counter - Fixed Prime Check: Corrected loop logic and added performance optimizations
- Thread-Safe Increment: Locked the counter modification to prevent race conditions
- Clean Thread Termination: Break out of the loop when the counter limit is hit, avoiding infinite exception loops
内容的提问来源于stack exchange,提问作者Trijit

