3

次の部分は、の4つの異なる実装をテストするJUnitテストケースからのものですSorterSorterこれは、 vizを持つ唯一のメソッドを呼び出しますsort()

sort()2秒より長くかかる場合はソートプロセスを強制終了したい( 500000と言うのに2秒より長くかかる実装は気にしないためIntegers)。

私はJavaマルチスレッドを初めて使用し、SOで他のすべてのスレッド( Javaスレッドを強制終了する方法と他のいくつかのスレッド)を調べた後、問題の解決策として次のことを考えました。質問は、それは一貫して機能するのでしょうか、それとも何か問題があるのでしょうか?reset()配列やその内容をリセットするので、その内容を気にしません。

私がそれを非協力的と呼ぶ理由s.sort()は、私のコントロールが及ばないからです。

protected E[] arr;
@Test
public void testSortTArray() {
    boolean allOk = true;
    for (Sorter s : TestParams.getSorters()) {
        System.out.println("Testing: " + s.getName() + " with " + arrayLenToTestWith + " elems of type "
                + classOfElemType.getName());
        reset();
        long startTime = System.nanoTime();
        MyThread test = new MyThread(s, arr);
        test.start();
        try {
            test.join(TestParams.getTimeThreshold());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (test.isAlive())
            test.interrupt();

        if (!test.isInterrupted()) {
            System.out.println("Time taken: " + ((System.nanoTime() - startTime) / (1000000)) + "ms");
            if (!isSorted(arr)) {
                allOk = false;
                System.err.println(s.getName() + " didn't sort array.");
            }
        } else {
            allOk = false;
            System.err.println(s.getName() + " took longer than .");
        }
    }
    assertTrue("At least one algo didn't sort the array.", allOk);
}

public class MyThread extends Thread {

    private Sorter s;
    private E[] arr;

    public MyThread(Sorter s, E[] arr) {
        this.s = s;
        this.arr = arr;
    }

    @Override
    public void run() {
        s.sort(arr);
    }
}

---編集:回答---

みんなからのコメントに基づく:

  • いいえ。スレッドを一時停止しないため、私が行っていることは安全ではありません。Thread.interrupt()スレッドのrun()実装によってチェックされない場合は役に立たない、中断された状態を設定するだけです。
    • この場合、次のソーターのsort()が同じ配列(古い「中断された」スレッドによってまだソートされている)で呼び出されるため、安全性が低下します。
  • 1つのオプションは、のProcess代わりに別のを作成することThreadです。AProcessを殺すことができます。
    • 明らかに、この場合、IPCが含まれるため、パラメーターの受け渡しは簡単ではありません。
4

4 に答える 4

3

あなたが言及した他の質問からinterrupt()わかるように、スレッドが(故意にまたは不注意に)テストした場合にonyが機能するため、協力なしにJavaスレッドを確実に停止することはできません。

ただし、プロセスを強制終了することは可能です。各ソートアルゴリズムを別々のプロセスで生成すると、強制的に強制終了できます。

欠点は、共有変数がないため、プロセスとの対話がスレッドとの対話よりも大幅に難しいことです。

于 2012-09-21T19:26:03.670 に答える
3

スレッドの協力がなければ、スレッドを停止するための信頼できる安全な方法はありません。スレッドの協力により、サポートされているメカニズムを使用してスレッドを中断または停止できます。スレッドはこの種の分離を提供しません...複数のプロセスを使用する必要があります。

于 2012-09-21T19:28:16.700 に答える
3

これは、Thread.stop()の場合です。ただし、特にjavadocの免責事項をお読みください。

非推奨。この方法は本質的に安全ではありません。Thread.stopを使用してスレッドを停止すると、ロックされているすべてのモニターのロックが解除されます(チェックされていないThreadDeath例外がスタックに伝播するのは当然の結果です)。これらのモニターによって以前に保護されていたオブジェクトのいずれかが一貫性のない状態にあった場合、損傷したオブジェクトが他のスレッドに表示され、任意の動作が発生する可能性があります。stopの多くの使用法は、ターゲットスレッドの実行を停止する必要があることを示すために変数を変更するだけのコードに置き換える必要があります。ターゲットスレッドはこの変数を定期的にチェックし、変数が実行を停止することを示している場合は、実行メソッドから整然と戻る必要があります。ターゲットスレッドが長期間(たとえば、条件変数で)待機する場合は、割り込みメソッドを使用して待機を中断する必要があります。

于 2012-09-21T19:40:13.687 に答える
2

それは一貫して機能しますか、それとも何か問題がありますか?

スレッド割り込みを正しく処理する必要があることを除いて、これは機能します。 メソッドがサポートしているthread.interrupt()場合にのみ機能します。このメソッドは、、、または他のそのようなメソッドsortを呼び出さないのではないかと思います。したがって、処理中に中断されているかどうかをテストする必要があります。Thread.sleep()wait()

 while (!Thread.currentThread().isInterrupted()) {
     // do sort stuff
 }

そうでない場合は、スレッドを中断しても処理は停止しません。test.join();別のソート操作を開始する前にスレッドが終了することを確認するために、割り込みの後に必ず別のものを追加します。

于 2012-09-21T19:21:54.893 に答える