0

現在のコードはシングルスレッドです。ファイルからデータを読み取り、乱数を生成し、その数が指定された間隔に属しているかどうかを確認します。

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;
    }
4

1 に答える 1

3

これをマルチスレッド化する最も簡単な方法は、プロデューサー/コンシューマー パターンを使用することです。1 つのプロデューサーがデータを読み取って に送信しBlockingQueue、コンシューマーが からデータを読み取りBlockingQueue( を使用take)、2 つの静的メソッドを使用して処理します。このようにして、最小限のリファクタリングを行う必要があります。静的メソッドはすでに再入可能/スレッドセーフであるため (VectorおよびParsedDataパラメータが共有されていないと仮定して)、変更する必要はまったくありません。

于 2013-05-14T19:24:21.890 に答える