0

私は並行性と呼ばれるこの怪物に立ち向かい、スレッドの知識を広げることにしました。そこで、ジョシュア・ブロックの本を読む前に、本を読む前に直面する可能性のある問題を理解するのに役立つランダムなコードを作成することにしました。私のコードと修正を行いますが、それから私はこのピットに着陸し、誰かが説明できることを望んでいます。

私は次のものを持っています:

public class Arithmetic implements Runnable {
    int number;    
    public  Arithmetic(int x){      
      this.number = number + x;
    }
    @Override
    public void run() {         
        Thread.currentThread().setName("thread-"+number +" > " + "number = "+getNumber());
        System.out.println(Thread.currentThread().getName());        
    }    
        public  int getNumber() {
        return number;
    }
    public  void setNumber(int number) {
        this.number = getNumber() + number;
    }
}

次に、メインクラス:

public class Main {  
    public static void main(String[] args) {    
      System.out.println(Thread.currentThread().getName());     
      for (int x=0; x<=5; x++){    
           Thread thread = new Thread(new Arithmetic(x));           
           thread.start();       
      }
    }
}

これにより、出力として次のようになります。

run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-5 > number = 5
thread-4 > number = 4

注意:5は4の前に来ます

しかし、メインクラスを次のように変更します。

public class Main {  
    public static void main(String[] args) {    
      System.out.println(Thread.currentThread().getName());     
      for (int x=0; x<=5; x++){    
           Runnable runnable  = new Arithmetic(x);           
          runnable.run();      
      }
    }
}

以下の出力が得られます。

run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-4 > number = 4
thread-5 > number = 5

注意:正しい順序

両方のメインが(スレッドの実装のように)不安定な結果を生成することを期待していたので、同期アクセスなどのスレッドセーフ対策を使用しますが、Runnable呼び出しArithmeticがスレッドセーフであるかのように動作するのはなぜですか?

IMO、Threadクラスの拡張とRunnableの実装の違いは、デカップリングを目的としています。これが重複した質問である場合はお詫び申し上げます。答えが見つからないようです。

前もって感謝します。

4

4 に答える 4

3

Runnables新しいスレッドを開始しないでください。これは単純でインターフェイスであるため、2番目のコードが同期して実行されることを意味します。

Threadsは新しいスレッドであるため、並行して実行できます。そのため、出力の順序が乱れます。4番目のスレッドは5番目のスレッドよりも実行速度が遅くなります。

于 2012-11-25T12:58:20.237 に答える
2

事はあなたがするときです

Thread t = new Thread(new Arithemetic())
 t.start();

スレッドtが開始され、実行されArithmeticます。

あなたの場合、あなたはを呼び出しています。runnable.run();これは、現在のスレッドがあなたの内部のコードを呼び出すことを意味しますrun()。他のメソッドを呼び出すのと似ています。

最終的に、現在のスレッド自体がrunメソッドを5回実行しています

于 2012-11-25T12:58:36.917 に答える
1

Runnableはすべてメインスレッドで実行されています(そのコードには「メイン」スレッドが1つだけあります)。

スレッドはすべて個別に実行されます。Javaは、一度開始されたスレッドが特定の順序で実行されることを保証しません。

于 2012-11-25T13:03:24.900 に答える
0

Runnableそれ自体は別のスレッドで実行されないためです。これは、メソッドの実装を渡すために使用される単なるインターフェースです。その一例は、Threadコンストラクターに渡すことです (最初の例で行ったように)。したがって、2 番目の例では、何も同時に実行されていません。run()メソッドを次々と実行しているだけです。

于 2012-11-25T12:59:54.137 に答える