1

次の Java コードがあります。

import java.io.*;
class Global{
public static int a = 0 ;
public static int b = 0 ;
}
public class Example{
public static void main(String args[]) {
    try {
        FileOutputStream fos = new FileOutputStream("1.dat");
        DataOutputStream dos = new DataOutputStream(fos);

        for (int i = 0; i < 20000; i++) {
            dos.writeInt(i);
        }
        dos.close();

        FileOutputStream fos1 = new FileOutputStream("2.dat");
        DataOutputStream dos1 = new DataOutputStream(fos1);

        for (int i = 20000; i < 40000; i++) {
            dos1.writeInt(i);
        }
        dos1.close();

        Exampless.createArray(20000); //static method call to set the static arr variable
        Exampless ex1 = new Exampless("1.dat"); //found number of matches in file
        Exampless ex2 = new Exampless("2.dat");
        Thread t1 = new Thread(ex1);
        Thread t2 = new Thread(ex2);
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        System.out.println("No. of Matches: " + (Global.a + Global.b ));

    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }
}
}

class Exampless implements Runnable {

public static int[] arr = new int[20000];
public String _name;

public Exampless(String name) {
    this._name = name;
}

static void createArray(int z) {
    for (int i = z; i < z + 20000; i++) {
        arr[i - z] = i;
    }
}

public void run() {
    try {
        int cnt = 0;
        FileInputStream fin = new FileInputStream(_name);
        DataInputStream din = new DataInputStream(fin);
        for (int i = 0; i < 20000; i++) {
            int c = din.readInt();
            if (c == arr[i]) {
                cnt++;
            }
        }
        System.out.println("File name: " + _name + " No. of Matches: " + cnt);
        if(_name == "1.dat")
            Global.a = cnt ;
        else if(_name == "2.dat")
            Global.b = cnt ;
    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }
}

}

runそこで、サンプル クラスメソッドを並列に実行しようとしています。ただし、を使用して行った子スレッドが終了するまでメインスレッドを待機させたいjoin。しかし、次々とスレッドを実行していきます。誰でもこれを解決する方法を教えてくれますか? もう1つのポイントは、グローバルクラスを使用して一致の総数を見つけた2つのスレッド間で変数(ファイル内の一致数を見つけたcntという名前)を共有したいということです。他に良い解決策はありますか?

4

3 に答える 3

4

t1.join()t1 が完了するまで待機するため、2 行を反転する必要があります。

t1.start();
t2.start();
t1.join();
t2.join();

ただし、高レベルの同時実行パッケージ、および通常はExecutorServiceを使用する方がよいでしょう:

ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(ex1);
executor.submit(ex2);
executor.shutdown();

次の質問:

グローバルクラスを使用して一致の総数を見つけた2つのスレッド間で変数(ファイル内の一致数を見つけたcntという名前)を共有したいと思います。他に良い解決策はありますか?

これらの変数が揮発性でない限り、あなたがしていることはスレッドセーフではありません。そうでない場合、メインの印刷でそれらの変数の最新の値が印刷されない可能性があります。

より良い解決策は、サンプルに Runnable の代わりにCallableを実装させることです。この場合、値を返すことができます。

次に、エグゼキューターによって返された未来から値を取得できます。

Future<Integer> future1 = executor.submit(ex1);
Future<Integer> future2 = executor.submit(ex2);

count1 = future1.get();
count2 = future2.get();

future.get()ps:呼び出しの周りにエラー処理コードを追加する必要があります

于 2012-07-29T20:12:48.577 に答える
1

前のスレッドが終了した後に次のスレッドを開始するのではなく、CountDownLatchを使用してスレッドの状態を監視します。

于 2012-07-29T20:14:40.297 に答える
1

参加する前に、最初に両方のスレッドを開始してみましたか?

    t1.start();
    t2.start();
    t1.join();
    t2.join();
于 2012-07-29T20:12:02.083 に答える