0

今回はマルチスレッドを使用する以外は、既に完了したタスクを実行したいと考えています。ファイルから大量のデータを (1 行ずつ) 読み取り、各行からいくつかの情報を取得して、それを Map に追加する必要があります。ファイルの長さは 100 万行を超えているため、マルチスレッドの恩恵を受ける可能性があると考えました。

Javaでマルチスレッドを使用したことがないため、ここでのアプローチについてはよくわかりません。メインメソッドに読み取りを実行させ、読み取った行を別のスレッドに渡して文字列をフォーマットし、それを別のスレッドに渡してマップに入れたいと考えています。

public static void main(String[] args)
{
    //Some information read from file
    BufferedReader br = null;
    String line = '';
    try {
        br = new BufferedReader(new FileReader("somefile.txt"));
        while((line = br.readLine()) != null) {
            // Pass line to another task
        }


    // Here I want to get a total from B, but I'm not sure how to go about doing that

}


public class Parser extends Thread
{
    private Mapper m1;

    // Some reference to B
    public Parse (Mapper m) {
        m1 = m;
    }

    public parse (String s, int i) {
        // Do some work on S
        key = DoSomethingWithString(s);
        m1.add(key, i);
    }

}

public class Mapper extends Thread
{
    private SortedMap<String, Integer> sm;
    private String key;
    private int value;
    boolean hasNewItem;

    public Mapper() {
        sm = new TreeMap<String, Integer>;
        hasNewItem = false;
    }

    public void add(String s, int i) {
        hasNewItem = true;
        key = s;
        value = i;
    }

    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                if (hasNewItem) {
                    // Find if street name exists in map
                    sm.put(key, value);
                    newEntry = false;
                }   
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        // I'm not sure how to give the Map back to main. 
    }
}

正しいアプローチを取っているかどうかはわかりません。また、Mapper スレッドを終了してメインでマップを取得する方法もわかりません。複数の Mapper スレッドを用意しますが、上記のコードでインスタンス化したのは 1 つだけです。

また、Parse クラスはスレッドではなく、run() メソッドをオーバーライドしない場合は別のクラスにすぎないことに気付いたので、Parse クラスはある種のキューであるべきだと考えています。

そしてアイデア?ありがとう。

編集:すべての返信に感謝します。I/O が主要なボトルネックになるため、これを並列化しても効率のメリットはほとんどないようです。ただし、デモンストレーションの目的で、正しい軌道に乗っていますか? マルチスレッドの使い方がわからないので、まだ少し悩んでいます。

4

3 に答える 3

6

なぜ複数のスレッドが必要なのですか? ディスクは 1 つしかなく、非常に高速にしか動作しません。この場合、マルチスレッドは役に立ちません。ほぼ確実です。もしそうなら、それはユーザーの観点からは非常に最小限になります. マルチスレッドはあなたの問題ではありません。巨大なファイルからの読み取りがボトルネックです。

于 2013-07-30T20:56:08.127 に答える
2

多くの場合、I/O はメモリ内タスクよりもはるかに時間がかかります。このような作業をI/O バウンドと呼びます。並列処理はせいぜいわずかな改善であり、実際には事態を悪化させる可能性があります。

何かをマップに入れるのに別のスレッドは必要ありません。解析が異常に高価でない限り、別のスレッドも必要ありません。

これらのタスクに別のスレッドがある場合、次の行が読み取られるのを待つためにほとんどの時間を費やしている可能性があります。

I/O を並列化しても必ずしも効果があるとは限らず、害を及ぼす可能性があります。CPU が並列スレッドをサポートしていても、ハード ドライブが並列読み取りをサポートしていない場合があります。

編集:

これについてコメントした私たち全員が、このタスクはおそらく I/O バウンドであると想定していました。ただし、以下のコメントから、このケースは例外であることが判明しました。より良い答えには、以下の 4 番目のコメントが含まれていたでしょう。

ファイル内のすべての行を処理せずに読み取るのにかかる時間を測定します。それらの読み取りと処理の両方にかかる時間を比較してください。これにより、節約できる時間の上限が緩くなります。これは、スレッド同期の新しいコストによって減少する可能性があります。

于 2013-07-30T20:55:54.517 に答える