-2
    //$Id$    
import java.util.logging.Level;
import java.util.logging.Logger;

public class ThreadSafe {

    public static final Logger LOGGER = Logger.getLogger(ThreadSafe.class.getName());

    public static int  random(int num){
        LOGGER.log(Level.INFO,"Entered Num : {0}",num);
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            LOGGER.log(Level.INFO,"Interrupted Exception");
        }
        return num + 2;
    }

    public static void main(String[] args){
        for(int threads=1;threads<100;threads++){
            final int number = threads;
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    int val = ThreadSafe.random(number);
                    System.out.println("Excepted Value = " + (number+2) + " Returned Value = " + val);
                }

            },"Thread : "+threads);
            thread.start();
        }
    }


}

出力:

30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 2
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 45
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 44
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 43
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 42
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 38
Excepted Value = 47 Returned Value = 47
30 Jan, 2013 11:41:26 PM com.zoho.learn.test.ThreadSafe random
INFO: Entered Num : 41
Excepted Value = 44 Returned Value = 44
Excepted Value = 46 Returned Value = 46

同じメソッドに同時にアクセスするマルチスレッドを除いています。静的メソッドに同時にアクセスするとどうなりますか?

競合状態が発生したのはいつですか?

共有状態とは何ですか?

私が間違っている場合は私を訂正してください。

4

3 に答える 3

3

run()同時に実行される唯一のコード ( を除く) は次のとおりです。

public static int  random(int num){
    LOGGER.log(Level.INFO,"Entered Num : {0}",num);
    try {
        Thread.sleep(5);
    } catch (InterruptedException e) {
        LOGGER.log(Level.INFO,"Interrupted Exception");
    }
    return num + 2;
}

ロギングの削除 (すべての正常な実装でスレッド セーフ)、スリープ (現在のスレッドにのみ影響する)、および例外処理を行うと、次のようになります。

public static int  random(int num){
    return num + 2;
}

引数は各スレッドに対してプライベートであるだけでなくnum(各スレッドには独自のスタック メモリがあります)、変更されることもありません。したがって、プログラムで競合状態が発生することはありません。

コードに共有状態 (グローバル変数) はありません。競合状態は、1 つのスレッドが共有データを変更し、他のスレッドがそれを読み取っている場合にのみ可能です。

競合状態を見たいですか?どうぞ!

private volatile int globalNum;

public static int  random(int num){
    globalNum = num;
    try {
        Thread.sleep(5);
    } catch (InterruptedException e) {
        LOGGER.log(Level.INFO,"Interrupted Exception");
    }
    return globalNum + 2;
}

災害からの最後の数秒:

  1. スレッド 1 が に入りrandom(42)、割り当てglobalNum = 42てスリープ状態になります

  2. スレッド 2 に入りrandom(17)、割り当てglobalNum = 17てスリープ状態になります

  3. スレッド 1 はウェイクアップし、globalNum(これは です) の現在の値を読み取り、期待どおりではなく17戻ります。1944

こちらもご覧ください

于 2013-01-30T18:25:03.960 に答える
0

同時に同じメソッドにアクセスするマルチスレッドを除外しています。

複数のスレッドが同じメソッドにアクセスしても問題ありません。競合状態は、複数のスレッドが同じ状態にアクセスする場合にのみ発生します。プログラムに共有状態がないため、競合状態はありません。

于 2013-01-30T18:24:37.417 に答える
0

共通のリソースにアクセスする場合、マルチスレッドが重要になります。
これは、一方のスレッドが読み取り中に他方のスレッドが変更する静的変数にすることができます。

各スレッドには独自のローカル変数があるため、ローカル変数やメソッド呼び出しは影響を受けません。

トレッド間で共有される共通のリソースはありません。

于 2013-01-30T18:28:07.197 に答える