0

私は次のコードを持っていますが、その出力は私が期待したものではありません:

public class ThreadManager {
    public static void main(String[] args) {
        Resource sharedResource = new Resource();
        new Thread(new MyThread(sharedResource)).start();
        new Thread(new MyThread(sharedResource)).start();
    }
}

class MyThread implements Runnable{
    Resource rs = null;
    public MyThread(Resource param) {
        this.rs = param;
    }
    @Override
    public void run() {
        this.rs.add(Thread.currentThread().getName());
        System.out.println(this.rs.str);
    }
}

class Resource{
    StringBuilder str = new StringBuilder();
    public void add(String text){
        str.append(text);
    }
}

出力は:

Thread-0Thread-1
Thread-0Thread-1

しかし、どのように...

ここで、スレッド0が最初に実行される場合、出力は次のようになります。

Thread-0
Thread-0Thread-1

しかし、ここでの問題は、出力の最初の行のスレッド1です。

4

2 に答える 2

2

ここで、スレッド0が最初に実行された場合、出力されます

スレッド0を最初に開始addしたからといって、最初にメソッド呼び出しに到達するとどう思いますか?また、一方のスレッド最初に呼び出しに到達したとしても、もう一方のスレッドがを呼び出す機会が得られる前に、次のステートメント( )にadd到達するという意味ではありません。それがここの状況のように見えます:System.out.printlnadd

  • Thread0呼び出しadd
  • Thread1呼び出しadd
  • Thread0呼び出しSystem.out.println(this.rs.str)
  • Thread1呼び出しSystem.out.println(this.rs.str)

(これは、不可分操作ではないという点で少し手間がかかりますが、フローの可能性はあります。)

2つのスレッドがランニングトラックのアスリートであると想像してください。スレッドを開始する順序は、必ずしもフィニッシュラインを通過する順序と同じではありません。

StringBuilderまた、複数のスレッドからのアクセスに対して安全であるように設計されていないことにも注意してください。

于 2012-10-07T08:38:35.090 に答える
0

見た目ほど単純なシステムではありません。スレッドは、printLn() 内のロックでスワッピングされています。

于 2012-10-07T08:49:01.843 に答える