1

私はこのコードを試していますが、得られた出力に少し混乱/驚いています。私はまだJavaに慣れていませんが、スレッドは通常同時に実行する必要があることを認識しています。ここでの「printB」スレッドは、実行を開始する前に「printA」スレッドを待機しているようです。私はプログラムを数回実行しました(両方のスレッドの結果の混合物、つまりa、a、b、a、b、a ...のようなものを取得することを望んでいますが、それでも同じ出力が得られます(つまり、「A」 「B」の前に最初に印刷されます)。なぜこれが起こっているのですか? また、コードを変更して正常に動作するようにするにはどうすればよいですか?

入力/提案は大歓迎です。ありがとう。

また、 extends Thread メソッドを使用して同じコードを試していますが、機能しません。

class PrintChars implements Runnable{
    private char charToPrint;
    private int times;

    public PrintChars(char c, int t){
        charToPrint = c;
        times = t;        
    }


    public void run(){
        for (int i=0; i<times; i++)
        System.out.println(charToPrint);        
    }


    public static void main(String[] args){

        PrintChars charA = new PrintChars('a', 7);
        PrintChars charB = new PrintChars('b', 5);

        Thread printA = new Thread(charA);
        Thread printB = new Thread(charB);

        printA.start();
        printB.start();
    }
}

以下の Thread メソッドを拡張します。

class PrintChars extends Thread {

private Char charToPrint;
private int times;


public PrintChars(char c, int t){
    charToPrint = c;
    times = t;
}


public void run (){

    for(int i =0; i<times; i++)
            System.out.println(charToPrint);
    }

    PrintChars printA = new PrintChars('a', 7);
    PrintChars printB = new PrintChars('a', 5);

    printA.start();
    printB.start();
}  
4

6 に答える 6

6

マルチスレッドでは、通常、出力について何の仮定もできません。

おそらく、スレッドの作成に費やされた時間が非常に長いため、実行が非常に短いため、前のスレッドが完全に完了する時間があります。

7 と 5 の代わりに 7000 と 5000 を試してください。

于 2013-08-03T14:49:35.567 に答える
4

各スレッドは開始に時間がかかり、非常に短時間で完了することができます。Thread.sleep(500);各行を印刷した後に追加することをお勧めします。

try {
    for(int i =0; i<times; i++) {
        System.out.println(charToPrint);
        Thread.sleep(500);
    }
} catch(InterruptedException ie) {
}
于 2013-08-03T14:51:14.733 に答える
2

スレッドのスケジューリングは決定論的ではありません。OS が 1 つのスレッドをスケジュールし、最初のスレッドが完了した後に 2 番目のスレッドのみをスケジュールすることはまったく問題ありません。

OS の観点から考えると、それは理にかなっています。誰かが 2 つのタスクを実行するように依頼した場合、一方を実行してからもう一方を実行する方が効率的かもしれません。

タスクの実行に時間がかかりすぎる場合、OS として、おそらくタスクを切り替えて他のタスクで何かを実行する必要があります。そうしないと、他のタスクがまったく進行せず、アプリも停止します。タスクを発行した人は差別されていると感じるでしょう。

Thread.sleepこれは、ステートメントを追加したり、PI などを計算したり (または 70000 のように 7 回以上ループするなど) 、タスクの実行時間を長くすることで確認できます。

于 2013-08-03T14:50:30.090 に答える
2

スレッドの実行時間が短すぎて効果が見られないと思います。に対してより高い値を試すことができますtimes。私は何かを試してみます>10000。もう 1 つのオプションは、メソッドを遅くして実行時間を増やすことです。

public void run(){
    for (int i = 0; i < times; i++) {
      System.out.println(charToPrint); 
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
}
于 2013-08-03T14:51:27.193 に答える
2

さらに数回実行してみてください。700/500で試してみると、織り交ぜていることに気づきました。

于 2013-08-03T14:53:11.667 に答える