Java -如何使这些方法多线程



当前代码是单线程的。它从文件中读取数据,生成随机数并检查这些数字是否属于给定的区间。

import java.io.*;
import java.util.*;
class Generator {
    private double mean;
    private double variance;
    private long amountOfNumbersToGenerate;
    public Generator(double mean, double variance, long amountOfNumbersToGenerate) {
        this.mean = mean;
        this.variance = variance;
        this.amountOfNumbersToGenerate = amountOfNumbersToGenerate;
    }
    double getMean() {
        return mean;
    }
    double getVariance() {
        return variance;
    }
    long getAmountOfNumbersToGenerate() {
        return amountOfNumbersToGenerate;
    }
}
class Interval {
    private double start;
    private double end;
    public Interval(double start, double end) {
        this.start = start;
        this.end = end;
    }
    double getStart() {
        return start;
    }
    double getEnd() {
        return end;
    }
}
class ParsedData {
    private Vector<Generator> generators;
    private Vector<Interval> intervals;
    public ParsedData(Vector<Generator> generators, Vector<Interval> intervals) {
        this.generators = generators;
        this.intervals = intervals;
    }
    Vector<Generator> getGenerators() {
        return generators;
    }
    Vector<Interval> getIntervals() {
        return intervals;
    }
}
class Worker extends Thread {
    public Worker() {
    }
}
class Start {
    static ParsedData readDataFromFile(String path) throws IOException {
        File file = new File(path);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line;
        line = br.readLine();
        String delimiter = "\s+";
        // generators
        long generatorSize =  Long.parseLong(line);
        Vector<Generator> generators = new Vector<Generator>();
        for(long i =0; i < generatorSize; i++) {
            line = br.readLine();
            Scanner f = new Scanner(line);
            f.useLocale(Locale.US); //without this line the program wouldn't work on machines with different locales
            f.useDelimiter(delimiter);
            Generator g = new Generator(f.nextDouble(), f.nextDouble(), f.nextInt());
            generators.add(g);
        }
        line = br.readLine();
        long intervalSize = Long.parseLong(line);
        Vector<Interval> intervals = new Vector<Interval>();
        for(long i = 0; i < intervalSize; i++) {
            line = br.readLine();
            System.out.println(line);
            Scanner f = new Scanner(line);
            f.useLocale(Locale.US); //without this line the program wouldn't work on machines with different locales
            f.useDelimiter(delimiter);
            Interval interval = new Interval(f.nextDouble(), f.nextDouble());
            intervals.add(interval);
        }
        br.close();
        return new ParsedData(generators, intervals);
    }
    static double boxMullerMarsagliaPolarRand(double mean, double variance) {
        double micro = mean;
        double sigma = Math.sqrt(variance);
        double y, x, omega;
        Random random = new Random();
        do {
            x = random.nextDouble();
            y = random.nextDouble();
            omega = x * x + y * y;
        } while (!(0.0 < omega && omega < 1.0));
        double sigma_sqrt = sigma * Math.sqrt(-2.0 * Math.log(omega) / omega);
        double g = micro + x * sigma_sqrt;
        // float h = micro + y * sigma_sqrt;
        return g;
    }
    /////////////////////////////////////////
    // TODO: refactor code into multithreaded
    static Vector<Double> generateRandomNumbers(ParsedData parsedData) {
        Vector<Double> generatedNumbers = new Vector<Double>();
        for(int i = 0; i < parsedData.getGenerators().size(); i++) {
            Generator g = parsedData.getGenerators().get(i);
            for(long j = 0; j < g.getAmountOfNumbersToGenerate(); j++) {
                double random = boxMullerMarsagliaPolarRand(g.getMean(), g.getVariance());
                generatedNumbers.add(random);
            }
        }
        return generatedNumbers;
    }
    /////////////////////////////////////////
    // TODO: refactor code into multithreaded
    static int[] checkIntervals(ParsedData parsedData, Vector<Double> generatedNumbers) {
        int[] numberOfHits = new int[parsedData.getIntervals().size()];
        for(int j = 0; j < parsedData.getIntervals().size(); j++) {
            Interval interval = parsedData.getIntervals().get(j);
            for(int i = 0; i < generatedNumbers.size(); i++) {
                if (interval.getStart() < generatedNumbers.get(i) && generatedNumbers.get(i) < interval.getEnd()) {
                    numberOfHits[j]++;
                }
            }
        }
        return numberOfHits;
    }
    public static void main(String args[]) {
        int amountOfThreads = Integer.parseInt(args[0]);
        String path = System.getProperty("user.dir") + "/input.dat";
        ParsedData parsedData = null;
        try {
            parsedData = readDataFromFile(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(parsedData.getGenerators().size());
        System.out.println(parsedData.getIntervals().size());
        Vector<Double> generatedNumbers = generateRandomNumbers(parsedData);
        int[] numberOfHits = checkIntervals(parsedData, generatedNumbers);
        for (int i = 0; i < numberOfHits.length; i++) {
            Interval interval = parsedData.getIntervals().get(i);
            System.out.println("" + (i+1) + " " + interval.getStart() + " " + interval.getEnd() + " " + numberOfHits[i]);
        }
        System.out.println(generatedNumbers.size());
    }
}

我不期望任何人为我编写或重构代码。

但是我不知道如何使这个方法多线程:

   /////////////////////////////////////////
    // TODO: refactor code into multithreaded
    static Vector<Double> generateRandomNumbers(ParsedData parsedData) {
        Vector<Double> generatedNumbers = new Vector<Double>();
        for(int i = 0; i < parsedData.getGenerators().size(); i++) {
            Generator g = parsedData.getGenerators().get(i);
            for(long j = 0; j < g.getAmountOfNumbersToGenerate(); j++) {
                double random = boxMullerMarsagliaPolarRand(g.getMean(), g.getVariance());
                generatedNumbers.add(random);
            }
        }
        return generatedNumbers;
    }
    /////////////////////////////////////////
    // TODO: refactor code into multithreaded
    static int[] checkIntervals(ParsedData parsedData, Vector<Double> generatedNumbers) {
        int[] numberOfHits = new int[parsedData.getIntervals().size()];
        for(int j = 0; j < parsedData.getIntervals().size(); j++) {
            Interval interval = parsedData.getIntervals().get(j);
            for(int i = 0; i < generatedNumbers.size(); i++) {
                if (interval.getStart() < generatedNumbers.get(i) && generatedNumbers.get(i) < interval.getEnd()) {
                    numberOfHits[j]++;
                }
            }
        }
        return numberOfHits;
    }

使其多线程的最简单方法是使用生产者-消费者模式,一个生产者读取数据并将其发送给BlockingQueue,消费者从BlockingQueue读取数据(使用take)并使用两个静态方法处理它。这样你只需要做最少的重构——静态方法已经是可重入/线程安全的(假设VectorParsedData参数不被共享),所以它们根本不需要修改。

最新更新