Java多线程:多类实现整数统计值计算的方案咨询
Hey there! Let's walk through this step by step—since you're new to Java and multi-threading, I'll keep things clear and avoid overly technical jargon where I can. Your plan of using four classes (one main + three calculation classes) is totally solid, so let's break down exactly how to make this work.
1. 整体职责拆分
First, let's lock in what each class will do to keep things organized:
- 主程序类: Handles preparing your 10 integers, creating/starting the three calculation threads, waiting for all threads to finish, and finally printing out all the results.
- AverageCalculation类: Dedicated thread for calculating the average of the 10 numbers.
- VarianceCalculation类: Thread for computing variance (the deviation-related stat you mentioned).
- Third Calculation Class: If you meant another stat like standard deviation (which relies on variance), we can add that too—adjust based on your exact "deviation" need.
2. Thread Implementation Best Practice
In Java, you can make threads two ways: extending the Thread class or implementing the Runnable interface. Go with Runnable—it's more flexible because your class can still inherit from other classes later if needed. Each calculation class will implement Runnable and override the run() method, where the actual calculation logic lives.
3. Sharing Data Safely
All three threads need access to the same 10 integers. The good news: if your list of numbers is immutable (meaning you don't change it after initializing), you don't need any fancy thread-safety code. Multiple threads reading the same unchanging data won't cause issues. So pass this immutable list to each calculation class via their constructor.
4. Retrieving Calculation Results
Each calculation class needs to store its result so the main class can grab it later. Add a getter method to each—like getAverage() or getVariance()—so once the thread finishes, the main class can fetch the computed value.
5. Coordinating Threads in the Main Class
The main class has a few key jobs:
- Initialize your 10 integers (hardcode them, generate randomly, whatever works for you).
- Create instances of each calculation class, passing the number list (and any dependent results, like variance needing the average).
- Wrap each calculation instance in a
Threadobject. - Start the threads—note: if some stats depend on others (like variance needs average), use
thread.join()to wait for the dependent thread to finish before starting the next one. - Once all threads are done, use the getter methods to pull results and print them.
Full Code Example
Here's a working example to tie it all together:
Main Class: StatisticsMain.java
import java.util.Arrays; import java.util.List; public class StatisticsMain { public static void main(String[] args) { // Prepare your 10 integers List<Integer> numbers = Arrays.asList(12, 45, 7, 89, 23, 56, 3, 78, 34, 67); // Create calculation instances AverageCalculation averageCalc = new AverageCalculation(numbers); VarianceCalculation varianceCalc = new VarianceCalculation(numbers, averageCalc); StandardDeviationCalculation stdDevCalc = new StandardDeviationCalculation(varianceCalc); // Wrap in Thread objects Thread averageThread = new Thread(averageCalc); Thread varianceThread = new Thread(varianceCalc); Thread stdDevThread = new Thread(stdDevCalc); // Start threads with dependencies in mind averageThread.start(); try { // Wait for average to finish before calculating variance averageThread.join(); varianceThread.start(); varianceThread.join(); stdDevThread.start(); stdDevThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } // Output all results System.out.println("Original 10 numbers: " + numbers); System.out.printf("Average: %.2f%n", averageCalc.getAverage()); System.out.printf("Variance: %.2f%n", varianceCalc.getVariance()); System.out.printf("Standard Deviation: %.2f%n", stdDevCalc.getStandardDeviation()); } }
Average Calculation Class: AverageCalculation.java
import java.util.List; public class AverageCalculation implements Runnable { private final List<Integer> numbers; private double average; public AverageCalculation(List<Integer> numbers) { this.numbers = numbers; } @Override public void run() { int sum = 0; for (int num : numbers) { sum += num; } average = (double) sum / numbers.size(); System.out.println("Average calculation complete!"); } public double getAverage() { return average; } }
Variance Calculation Class: VarianceCalculation.java
import java.util.List; public class VarianceCalculation implements Runnable { private final List<Integer> numbers; private final AverageCalculation averageCalc; private double variance; public VarianceCalculation(List<Integer> numbers, AverageCalculation averageCalc) { this.numbers = numbers; this.averageCalc = averageCalc; } @Override public void run() { double avg = averageCalc.getAverage(); double sumOfSquaredDifferences = 0; for (int num : numbers) { sumOfSquaredDifferences += Math.pow(num - avg, 2); } // Use numbers.size() for population variance, numbers.size()-1 for sample variance variance = sumOfSquaredDifferences / numbers.size(); System.out.println("Variance calculation complete!"); } public double getVariance() { return variance; } }
Standard Deviation Calculation Class: StandardDeviationCalculation.java
public class StandardDeviationCalculation implements Runnable { private final VarianceCalculation varianceCalc; private double standardDeviation; public StandardDeviationCalculation(VarianceCalculation varianceCalc) { this.varianceCalc = varianceCalc; } @Override public void run() { standardDeviation = Math.sqrt(varianceCalc.getVariance()); System.out.println("Standard deviation calculation complete!"); } public double getStandardDeviation() { return standardDeviation; } }
Key Notes to Remember
- Thread Dependencies: If one stat relies on another (like variance needs average), use
join()to enforce order—this prevents trying to read an uncomputed result. - Immutability = Safety: By using an immutable list (from
Arrays.asList()), we avoid thread-safety issues entirely. If you ever need a mutable list later, use thread-safe collections likeCopyOnWriteArrayListor synchronize access withsynchronizedblocks. - Exception Handling: The
join()method throwsInterruptedException, so make sure to catch it (like in the example) or declare it in your method signature.
内容的提问来源于stack exchange,提问作者enerji

