-1

以下のコードを参照してください。これは、Oracle のチュートリアル ページから変更されたコード サンプルです。

public class BadThreads {
    static String message;

private static class CorrectorThread extends Thread {
    public void run() {
        try {
            sleep(1000); 
        } catch (InterruptedException e) {}
        message = "Mares do eat oats."; 
        System.out.println("1: "+ message);
    }    
}

public static void main(String args[]) throws InterruptedException {

    CorrectorThread c=new CorrectorThread();

    c.start();
    System.out.println("0: "+ message);
    c.run(); 
    System.out.println("2: "+ message);

    message = "Mares do not eat oats.";
    System.out.println("3: "+ message);

    Thread.sleep(2000);
    System.out.println("4: "+ message);
}
}

版画

0: null
1: Mares do eat oats.
1: Mares do eat oats.
2: Mares do eat oats.
3: Mares do not eat oats.
4: Mares do not eat oats.

そして大丈夫です。

コメントアウトしたら

c.run();

メインメソッドでは、私は得る

0: null
2: null
3: Mares do not eat oats.
1: Mares do eat oats.
4: Mares do eat oats.

maincの前に実行されるのはなぜですか? スレッドcは、その「親」スレッドmainと同じ優先度を持っています。

mainがcに表示されているため、cはmainが戻るのを待っていますか? これは意味がありませんが、私が考えることができる唯一のものです。

//============================

編集:交換

c.run(); 

c.join(); 

同じ効果とより細かいプログラミングのために。

4

5 に答える 5

4

スレッドの要点は、スレッドが並行して実行されることです。したがって、メイン スレッドはコレクター スレッドと並行して実行されます。そして、修正スレッドが最初に行うことは 1 秒間スリープすることであるため、修正スレッドがメッセージを変更する前に、メイン スレッドにはその命令を実行するための十分な時間があります。

于 2013-10-21T12:24:55.530 に答える
1

スレッド/メソッドを呼び出す順序のために、メインスレッドが最初または2番目になることについての保証がないため、これはここでは奇妙なことではありません。

最初c.start()に新しいスレッドを開始します。これは、メインがその仕事を続けることを意味します。したがって、最初の状況では、次のようなものがあります

0000->thread main starts the bad thread |  bad thread sleeps for 1 second
      and prints the message value(null)
0001->thread main runs the run() method |  bad thread still is sleeping
      with its thread
0002-> both thread are sleeping ....
0003->.....
1000->either bad thread or main thread changes the message value to "Mares do eat oats." (not sure which goes first!)
1001->thread main prints("1:" +message) |  bad thread prints("1:" +message)
1002->thread main prints("1:" +message) | bad thread has terminated X
1003->thread main changes the message value to "Mares do not eat oats."
1004->main threads prints the message again and sleeps for 2 seconds
2004->main thread prints the message again.

一方、2 番目の状況では、run()メイン スレッドによる呼び出しがないため、メイン スレッドは不良スレッドのように 1 秒間スリープせず、メッセージを出力して値を「Mares do not eat oats.」に変更しようとします。再び印刷し、2 秒間スリープし、その後 1 秒後に (メインスレッドがスリープ状態にある間に) 不良スレッドが起動すると、メッセージの値を変更して印刷し、2 秒後にメインスレッドが不良スレッドによって変更されたメッセージ。

答えはここにあります。実行順序が原因で、どちらのスレッドが最初または 2 番目に実行されるかについての保証はありません。このチュートリアルはあなたを助けるかもしれません。

于 2013-10-21T12:50:36.160 に答える
1

When you call c.run(), it executes the run function and wait for completion. The waiting will also cover the thread time parallel and you see two consective outputs in first case. In second case, the thread started and main runs parallel to run function, as run is in sleep and in that it covers the main showed statements.

c.start() starts the thread runs parallel to main. c.run(), calls the run function and on completion move to next statement.

于 2013-10-21T12:26:39.033 に答える
0

インラインコメントを見る

CorrectorThread c=new CorrectorThread();

c.start(); // new thread started, but up to scheduler to decide when to give it a slice of time
System.out.println("0: "+ message);
c.run(); // ran in main thread
System.out.println("2: "+ message); // as expected, message was set by the other thread

message = "Mares do not eat oats.";
System.out.println("3: "+ message); // as expected

Thread.sleep(2000);
System.out.println("4: "+ message); // as expected

c.start()両方ともc.run()最終的に呼び出しCorrectorThread#run()ますが、異なるスレッドになります。Threadどちらが最初に到達するかは、スケジューラ次第です。

c.run()スケジューラを呼び出さない例では、呼び出す時間があります

System.out.println("0: "+ message); // null

System.out.println("2: "+ message); // null

他のスレッドが初期化する前にmessage

于 2013-10-21T12:24:14.947 に答える
0

このようにしてみてください:-

public class BadThreads {
    static String message;

    private static class CorrectorThread extends Thread {
        public void run() {
            try {
                sleep(1000); 
            } catch (InterruptedException e) {}
            message = "Mares do eat oats."; 
            System.out.println("3: "+ message);
        }    
    }

    public static void main(String args[]) throws InterruptedException {

        CorrectorThread c=new CorrectorThread();
        c.start();

        System.out.println("0: "+ message); 
        System.out.println("1: "+ message);

        message = "Mares do not eat oats.";
        System.out.println("2: "+ message);

        Thread.sleep(2000);
        System.out.println("4: "+ message);
    }
}
于 2013-10-21T12:31:44.220 に答える