5

わかりました、おそらくスレッドが実際にどのように機能するかについての理解が不十分であることはわかっていますが、誰かが理解するのを手伝ってくれるまで、それはバグだと信じています:)

私の Main クラスとその main() メソッドには、次のものがあります。

public static void main(String args[]){
    StoneBucket stoneBucket = new StoneBucket();    
    StonePutter spRunnable   = new StonePutter(stoneBucket);
    StoneThrower stRunnable  = new StoneThrower(stoneBucket);
    StoneThrower stRunnable2 = new StoneThrower(stoneBucket);

    //Create the Threads that will take the Runnables as arguments
    Thread puttingThread = new Thread(spRunnable);
    Thread throwingThread = new Thread(stRunnable);
    Thread throwingThread2 = new Thread(stRunnable);

    puttingThread.setName("Putter");
    throwingThread.setName("Thrower 1");
    throwingThread2.setName("Thrower 2");
    [...]

そして、StoneThrower クラスでは、

public class StoneThrower implements Runnable{

private StoneBucket sb;
private String name;

public StoneThrower(StoneBucket _sb){
    this.sb = _sb;
}   

public void run(){

    name = Thread.currentThread().getName();        
    System.out.println("T::"+name+" started...");       
    int count = 0;      
    while(true){
            [...]

このコードをコンパイルして実行すると、次のようになります。

2 つのスレッドのスクリーンショット...

それで、私の質問は、これらのスレッドが両方とも同じ名前を返すのはなぜcurrentThread().getName()ですか? それらが作成されたときに名前が割り当てられ、threadX.setName("XXX")それらのランナブルは呼び出しによって開始されthreadX.start()ます...誰かが私にこれを明確にしてもらえますか?

編集: stRunnable を stRunnable2 に変更すると動作が期待どおりになるため、正しい答えを受け入れました。本当の問題は、なぜこれが起こるのかということです。2 つのスレッドを作成し、別々に開始します。run() メソッド (スレッドの作成時に 1 回呼び出される) が間違った名前を返す可能性はありますか?

4

2 に答える 2

9

これは、スレッド名を のインスタンス変数に格納するために発生しnameますStoneThrower。同時実行性のため、2 番目のスレッドは最初のスレッドが設定したばかりの値をオーバーライドしname、両方が同じ値を出力します。

これがあなたのシナリオです:

1. Thread1#start
2. Thread2#start
3. Thread1#runnable#run -> runnable.name = 'Thrower 1'
4. Thread2#runnable#run -> runnable.name = 'Thrower 2' // overrides
5. Thread1#runnable#run -> System.out.println(runnable.name)
6. Thread2#runnable#run -> System.out.println(runnable.name)
于 2012-11-28T21:03:10.377 に答える
5

同じランナブルで両方のスレッドを作成します。

Thread throwingThread = new Thread(stRunnable);
Thread throwingThread2 = new Thread(stRunnable);
                                    ^^^^^^^^^^ stRunnable2?

オブジェクトのインスタンス変数にスレッド名を格納しRunnableます。オブジェクトは 2 つのスレッドで共有されるため、実行する 2 番目のスレッドはname = Thread.currentThread().getName()、最初のスレッドの名前を独自の名前で上書きします。

于 2012-11-28T20:53:54.763 に答える