0

Java スレッドが順次実行されているように見える奇妙な動作を観察しています。以下はコードスニペットです

class ThreadUnsafeClass {

    private static int y;

    public static void incrementY() {
        y++;
    }

    public static int getY() {
        return y;
    }

}

public class MultiThreadedClass implements Runnable {
    int threadId;

    MultiThreadedClass (int threadId) {
        this.threadId = threadId;
    }

    @Override
    public void run() {

        System.out.println("Number:"+ threadId + ";Thread Unsafe Old Value:" + ThreadUnsafeClass.getY());

        try {
            if (threadId == 1 || threadId ==2) {
                Thread.sleep(60000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace(); 
        }
        ThreadUnsafeClass.incrementY();

        System.out.println("Number:"+ threadId + ";Thread Unsafe New Value:" + ThreadUnsafeClass.getY());
    }

    public static void main (String []args) {
        MultiThreadedClass thread1 = new MultiThreadedClass(1);
        MultiThreadedClass thread2 = new MultiThreadedClass(2);
        MultiThreadedClass thread3 = new MultiThreadedClass(3);
        MultiThreadedClass thread4 = new MultiThreadedClass(4);
        thread1.run();
        thread2.run();
        thread3.run();
        thread4.run();
   }
}

以下は同じ出力です。

Number:1;Thread Unsafe Old Value:0
Number:1;Thread Unsafe New Value:1
Number:2;Thread Unsafe Old Value:1
Number:2;Thread Unsafe New Value:2
Number:3;Thread Unsafe Old Value:2
Number:3;Thread Unsafe New Value:3
Number:4;Thread Unsafe Old Value:3
Number:4;Thread Unsafe New Value:4

上記の出力から、スレッド 1 と 2 が妥当な時間、つまり 60 秒間待機している場合でも、スレッド 3 と 4 は、実行が終了したときにのみ実行されることがわかります。スレッドが並行して実行されないのはなぜですか? また、一方のスレッドがスリープ状態になると、もう一方のスレッドがその実行を進めないのはなぜですか? 私はどこか間違っていますか?

4

3 に答える 3

6

実際のクラスではなく、Thread参照するRunnableand callを作成する必要があります。何かを作成しても、別のスレッドで自動的に実行されるわけではありません。start()run()Runnable

例えば

(new Thread(myRunnable)).start()

Runnableとの間の分離はなぜThreadですか? を取得Runnableして、スレッド プールにドロップできます。次に利用可能なスレッドがそれを実行しRunnableます。(たとえば、Java Executorフレームワークを参照)Runnableは、オブジェクトがスレッド化に使用できることのみを示します。

于 2012-11-05T14:36:57.253 に答える
3

メソッドを同期的に呼び出すため、の代わりに拡張Threadして呼び出す必要があります。は非同期に呼び出され、探している効果が得られます。thread.start()thread.run()thread1.run()thread.startrun()

このコンストラクターを使用してThreadから を構築することもできます。Runnable

Thread(Runnable r)

于 2012-11-05T14:38:11.340 に答える
2

Runnable別のスレッドで実行するクラスを実装するだけでは十分ではありません。それ以外の

MultiThreadedClass thread1 = new MultiThreadedClass(1);
MultiThreadedClass thread2 = new MultiThreadedClass(2);
MultiThreadedClass thread3 = new MultiThreadedClass(3);
MultiThreadedClass thread4 = new MultiThreadedClass(4);
thread1.run();
thread2.run();
thread3.run();
thread4.run();

やってみる

new Thread(new MultiThreadedClass(1)).start();
new Thread(new MultiThreadedClass(2)).start();
new Thread(new MultiThreadedClass(3)).start();
new Thread(new MultiThreadedClass(4)).start();
于 2012-11-05T14:38:35.833 に答える