0
class Useless {
    public static boolean b = true;

    public synchronized void u1() {
        try {
            while (b == true)
                wait();
        } catch (InterruptedException i) {
        }
    }

    public synchronized void u2() {
        if (b == true) {
            b = false;
        }
        notify();
    }
}

public class SleepMessages extends Thread {

private Useless u;

    public SleepMessages(Useless u) {
        this.u = u;
    }

    public void run() {
        String importantInfo[] = { "Mares eat oats", "Does eat oats" };
        for (int i = 0; i < importantInfo.length; i++) {
            u.u1();
            System.out.println(importantInfo[i] + " - " + getName());
            try {
                sleep(2000);
            } catch (InterruptedException e) {
            }
        }
    }

    public static void main(String args[]) throws InterruptedException {
        Useless u = new Useless();
        Thread t1 = new SleepMessages(u);
        t1.setName("t1");
        Thread t2 = new SleepMessages(u);
        t2.setName("t2");
        t1.start();
        t2.start();
        sleep(2000);
        System.out.println("Here they go!...");
        t1.interrupt();
        sleep(1000);
        t2.interrupt();
        u.u2();
        sleep(1000);
        u.u2();
    }
}

この小さなプログラムの出力は次のようになります: Here they go!... Mares eat oats - t1 Mares eat oats - t2 Does eat oats - t2 Does eat oats - t1

私の質問は、スレッド t2 が catch(InterruptedException e) に入る唯一のスレッドである理由と、結果が次のようなものではない理由です。

ほら、どうぞ!... 雌馬はオート麦を食べる - t1 雌馬はオート麦を食べる - t2 オート麦を食べる - t1 オート麦を食べる - t2

4

3 に答える 3

1

私の質問は、なぜスレッドt2がcatch(InterruptedException e)に入る唯一のものなのかということです。

t1.interrupt()run()メソッドでスリープを中断しているように見えます。InterruptedExceptionを破棄すると、スレッドが以前に中断されたことを知る方法はありません。

結果が次のようにならないのはなぜですか:ここに行きます!...マレスはオーツ麦を食べます-t1マレスはオーツ麦を食べます-t2オーツ麦を食べます-t1オーツ麦を食べます-t2

Javaはバイアスロックを使用します。これは、ロックを取得する最後のスレッドが最初に同じロックを取得する可能性が高いことを意味します。

于 2013-01-08T16:20:01.657 に答える
0

Useless のインスタンスは 1 つしかないため、ブール値 b は 1 つだけです。true に設定すると、SleepMessages の両方のインスタンスが待機ループを離れることができるため、実行する機会が発生した方が実行されるか、複数の CPU が同時にスレッドを実行している場合は両方が実行されます。

于 2013-01-08T16:32:46.330 に答える
0

あなたのコードをテストしたところ、両方のスレッドが問題なく中断されました。そのため、どちらのスレッドも catch ブロックに入らないと考える理由がわかりません。

u1()演習は、最初に割り込みを使用して (スレッドをトリガーして最初のメッセージを出力する)、b2 回目にブール値を設定する (2 番目のメッセージをトリガーする)ことで、待機から抜け出すことのようです。

の場合interrupt()、順序はかなり予測可能であり、メインスレッドが中断する前に取得するスリープの秒でt1、次の呼び出しに到達するのに十分な時間が得られます。u1()t2

部品の場合u2()、順序は予測しにくいものです。t1との両方t2が同じモニターで待機しています。コールはnotify()どちらかを起こす可能性があります。目を覚ますものは、2 番目のメッセージを出力し、もう少しスリープして停止します。2 番目notify()は、モニター上で待機している 1 つのスレッドをウェイクアップします。

したがって、最後の 2 つのメッセージの順序は不定です。

いくつかの最終的なアドバイス:あなたが達成したいと思われる動作は、おそらく使用して実装する方が簡単ですCyclicBarrier

于 2013-01-08T18:59:44.223 に答える