Java метод NotifyAll () не работает?

1

Я немного в тупике. Ниже приведена копия и вставка из простого сценария с использованием wait() и notify() в java.

Насколько я понимаю, эта программа Java ниже должна печатать yumyum.. на экране, но это не так. Я в Eclipse для Mac OS X. Есть идеи, что я делаю неправильно?

public class Main {
    public static void main(String[] args) {
        MyHouse house = new MyHouse();
        house.eatPizza();
        house.pizzaGuy();

    }
}

class MyHouse extends Thread {

    private boolean pizzaArrived = false;

    public void eatPizza() {
        synchronized (this) {
            while (!pizzaArrived) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        System.out.println("yumyum..");
    }

    public void pizzaGuy() {
        synchronized (this) {
            this.pizzaArrived = true;
            notifyAll();
        }
    }
}
Теги:
multithreading
wait

3 ответа

2
Лучший ответ

Попробуй это...

public class Main {

    public static void main(String[] args) {
        MyHouse house = new MyHouse();
        house.start();
//        house.eatPizza();
        // Halt main thread momentarily to delay Mr Pizza Guy
        try { Thread.sleep(3000); } catch(Exception e) {}
        house.pizzaGuy();

    }
}

class MyHouse extends Thread {

    private boolean pizzaArrived = false;
    private Object lock = new Object();

    @Override
    public void run() {
        eatPizza();
    }

    public void eatPizza() {
        synchronized (lock) {
            while (!pizzaArrived) {
                try {
                    System.out.println("Waiting for Pizza guy");
                    lock.wait();
                } catch (InterruptedException e) {
                }
            }
            System.out.println("Pizza arrived!!!");
        }
        System.out.println("yumyum..");
    }

    public void pizzaGuy() {
        synchronized (lock) {
            this.pizzaArrived = true;
            lock.notifyAll();
        }
    }
}
  • 0
    Это идеальный аноним. Спасибо!
  • 0
    Правильно, не используйте 'synchronized (this)', это приведет к блокировке основного объекта, а также заблокирует основной поток. Попробуй поставить блокировку на фиктивном объекте, и я буду работать как обычно.
3

У вас есть один поток. Единственный поток будет wait бесконечно (его нужно уведомить другим потоком). Попробуйте создать еще один поток, в котором будет eatPizza() и один будет pizzaGuy

  • 0
    Увы, до сих пор не работает. Вот мой обновленный main: <pre> открытый класс Main {public синхронизированный статический void main (String [] args) {MyHouse house = new MyHouse (); house.eatPizza (); MyHouse house1 = новый MyHouse (); house1.pizzaGuy (); }} </ pre>
  • 0
    @MartynChamberlin это еще хуже. Теперь у вас все еще есть только один поток, и вы вызываете синхронизированные методы двух разных объектов. Чтобы иметь поток, вам нужно где-нибудь вызвать start() для экземпляра Thread. В противном случае все выполняется основным потоком.
Показать ещё 2 комментария
0

Попробуйте под кодом работать нормально.

public class WaitNotify {

private static int i = 1;
private static boolean flag = false;
static Object obj = new Object();

public static void main(String[] args) {

    Thread t1 = new Thread(new Runnable(){

        @Override
        public void run() {
                while(i<10){
                    synchronized (obj) {
                        try {
                            if(i%2 == 0){
                                obj.wait();
                            }
                            System.out.println("t1 -> " + i++);
                            obj.notify();

                            Thread.currentThread().sleep(500);

                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }                       
                }   
        }           
    });

    Thread t2 = new Thread(new Runnable(){

        @Override
        public void run() {
            while(i<10){
                synchronized (obj) {
                    try {
                        if(i%2 != 0){
                            obj.wait();
                        }
                        System.out.println("t2 -> " + i++);
                        obj.notify();
                        Thread.currentThread().sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }                       
            }   
        }           
    });

    t1.start();
    t2.start();

    try {
        t1.join();
        t2.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню