-1

したがって、ランダムに生成された番号を見つけようとする3つのスレッドがあります(各スレッドにはstartNumとfinishNumという独自の範囲があります)。番号が見つかったために1つが停止した場合は、他のすべてのスレッドも停止します。

「揮発性」ブール値について読んだことがあります。これは明らかにすべてのスレッドが共有するブール値であるため、常に1つの値になります。

これは私が持っているコードです:(注:startNumberがfinishNumberを超えたためにスレッドが「停止」した場合、他のスレッドが進行している間にスレッドが終了しても問題ありません)

private volatile boolean numberFound = false;

public void run()
{
    while(startNum < finishNum) //what i'm talking about with the [note]
    {   
        search( startNum); 
        if(numberFound == true)
        {
            break;
        }       
    }   
}  
private synchronized void search(int startNum)
{
    for(int i = 0; i < 10; i++)
    {
        if( startNum != searchNum )
        {
            startNum++;
        }
        else if(startNum == searchNum )
        {
            numberFound = true;
            System.out.println( this.currentThread().getName() + " has found the number: " + searchNum );
            break;

        }

    }

}

また、プログラムが数値(スレッド)の各範囲でそれぞれ10回数値をチェックし、別の範囲に移動するようにしたいので、それぞれ10回ループしています。

要求に応じてスレッドを開始するmain()メソッドは次のとおりです。intrandomNum =(int)(Math.random()* 1001);

    FindIt t1 = new FindIt(randomNum, 0, 349); //FindIt extends Thread
    FindIt t2 = new FindIt(randomNum, 350, 699);
    FindIt t3 = new FindIt(randomNum, 700, 1000);

    t1.start();
    t2.start();
    t3.start(); 
4

3 に答える 3

4

3つのスレッドがこのクラスの異なるインスタンスにある可能性があるため、3つの異なるブール値を持つように見えます

ブール値を静的にして、何かが変わるかどうかを確認してください。

(スレッドを開始するコードが表示されないため、これ以上は役に立ちません)

注:揮発性とは、実際にはすべてのスレッドがそれを共有することを意味するのではなく、すべてのスレッドがそれを共有する場合、1つのスレッドでの変更が他のスレッドの同じ変数に反映されることを意味します。独立したキャッシュを備えたマルチCPUマシンでは、あるスレッドがバージョンを更新し、別のスレッドがすでにそのメモリをキャッシュしているために変更を取得しない可能性があるため、これが必要です。

于 2013-01-01T01:28:20.907 に答える
1

numberFoundそうでなければならないという答えstaticは正しいです。そして、でロックすることについての苦労も正しいです(ただし、ここでロックする必要synchronizedがあるかどうかは明らかではありません...)。

しかし、これは、差し迫った問題を引き起こしている並行性とは関係のない別のバグです。

while(startNum < finishNum) {   
    search(startNum); 
    if(numberFound == true)
    {
        break;
    }       
}

private synchronized void search(int startNum) {
    ... 
    if (startNum != searchNum) {
        startNum++;
    }
    ...

問題は、startNumインクリメントしているものが、ループstartNumでテストしているものと同じではないことです。whileJava では、引数は値渡しです。だから何が起こっているのですか:

  1. startNumメソッド内の値をrunメソッドに渡していますsearch
  2. メソッドはそれsearchをローカル変数に入れます。
  3. メソッドはsearchローカル変数を更新します。
  4. searchメソッドが戻り、更新されたローカル変数が開始されます。
  5. メソッドに戻るとrun、 の値はstartNum変更されていません。
于 2013-01-01T01:53:05.727 に答える
0

numberFoundは静的として宣言されていないため、各スレッドには独自のプロパティ値が個別に設定されます。同期メソッドでも同じです。各スレッドはそれ自体のロックを取得するため、実際にそのような検索メソッドを同期することは、おそらくあなたが望むものではありません。このメソッドを同期する理由を詳しく説明できますか?volatileについて詳しくは、http ://www.javamex.com/tutorials/synchronization_volatile.shtmlをご覧ください。

同期とロックの詳細:http: //docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

すべてのスレッド間で共有リソースとなる別のオブジェクトを用意することをお勧めします。このようなアプローチを使用すると、デフォルトのロックが共有オブジェクト自体で実行されるため、スレッドはオブジェクトのロックのために「戦い」を開始します。

于 2013-01-01T01:36:31.860 に答える