0

私は2つのスレッドを使用しようとしています。1つのスレッドは奇数のみを印刷し、もう1つのスレッドは偶数のみを印刷し、代替操作でなければなりません。

例えば:

Thread1 1
Thread2 2
Thread1 3
Thread2 4
and so on..

以下はプログラムです。スレッド2が通知している場合でも、スレッド1が待機状態から抜け出さないため、どこが間違っているか教えてください..

    public class ThreadInteraction {

    public static void main(String[] args) {
        new ThreadInteraction().test();
    }

    private void test() {
        ThreadA ta = new ThreadA();
        Thread t = new Thread(ta);
        t.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        for(int i=2;i<=50;){
            System.out.println("Thread2 "+i);
            synchronized (t) {
                try {
                    t.notify(); 
                    t.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            i=i+2;
        }
    }
}

    class ThreadA implements Runnable{
        @Override
        public void run() {
            for(int i=1;i<50;){
                System.out.println("Thread1 "+i);
                synchronized (this) {
                        try {
                            notify();                           
                            wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                }
                i=i+2;
            }
        }
    }
4

3 に答える 3

2

問題は、Thread t[synchronized (t)] をロックしている場合と、TheadAオブジェクト自体 [synchronized(this)] をロックしている場合があることです。

スレッドが互いに通信したい場合は、両方が同じオブジェクトに対してのみロックを取得する必要があり、待機通知は期待どおりに機能します。

編集:

プログラムには別の問題があります。変数を使用して 2 つのスレッド間を調整していません。SO 2,1,4,3... などの出力が表示される場合があります。ポイントは、スレッドが順番にではなく交互に機能することです。したがって、インクリメントする必要がある 2 つのスレッド間で単一の変数を共有する必要があります。2番目の問題は、偽のウェイクアップコールを処理していないことです[これに関するドキュメントを読んでください]。whileループ内で常にwaitを呼び出す必要があります。

于 2013-10-06T07:20:27.250 に答える
0

Lokesh から提供された回答に基づいてコードを変更しました

public class ThreadInteraction {
    public static void main(String[] args) {
        new ThreadInteraction().test();
    }
    private void test() {
        ThreadA ta = new ThreadA();
        Thread t = new Thread(ta);
        t.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        for(int i=2;i<=50;){
            System.out.println("Thread2 "+i);
            synchronized (ta) {
                try {
                    ta.notify();    
                    ta.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            i=i+2;
        }
    }
}
class ThreadA implements Runnable{
    @Override
    public void run() {
        for(int i=1;i<50;){
            System.out.println("Thread1 "+i);
            synchronized (this) {
                    try {
                        notify();                           
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            }
            i=i+2;
        }
    }
}
于 2013-10-06T07:24:53.567 に答える