Почему Java-поток wait () работает только с ограничением по времени? - PullRequest
2 голосов
/ 27 августа 2010

Я пытаюсь ознакомиться с потоками Java для SCJP, и у меня возник вопрос.

В приведенном ниже коде я просто создал: два Runnables с общее хранилище данных (массив) и синхронизированный метод write () для последовательного заполнения данными, оставляя букву в виде метки для каждого Runnable (A и B) в последовательности.

Я знаю, что код груб и может быть лучше написан, но я искал мораль потоков.

Так что теперь, когда я запускаю его, он никогда не заканчивается и результаты останавливаются на:

Все еще хорошо. A0.

Но когда я меняю wait () на wait (100), он отлично работает, считая от 0 до 9, и завершается нормально. Может ли кто-нибудь объяснить мне причину этого, пожалуйста?

Спасибо.

public class ArrayThreads {

Object[] array = new Object[10];
boolean isA = true;

    int position = 0;

    int getIndex(){
        return position;
    }



class ThreadA implements Runnable{

            synchronized void write(String value){
                    while(!isA){
            try {
                wait();
            } catch (InterruptedException ex) {
                System.out.println("An error in" + value);
                ex.printStackTrace();
            }
        }
        array[position] = value + position;
        System.out.println(array[position]);
        position++;
        isA = !isA;
        notify();
    }

    public void run() {
        while(getIndex()<array.length){
            if (getIndex()==9) return;
            else
        write("A");}
    }
}

    class ThreadB implements Runnable{

                synchronized void write(String value){
                    while(isA){
            try {
                wait();
            } catch (InterruptedException ex) {
                System.out.println("An error in" + value);
                ex.printStackTrace();
            }
        }
        array[position] = value + position;
        System.out.println(array[position]);
        position++;
        isA = !isA;
        notify();
    }

    public void run() {
        while(getIndex()<array.length){
            if (getIndex()==9) return;
            else
        write("B");}
    }
}

    public static void main(String[] args){
        ArrayThreads threads = new ArrayThreads();
        Thread threadA = new Thread(threads.new ThreadA());
        Thread threadB = new Thread(threads.new ThreadB());
        System.out.println("Still good");

        threadB.start();
        threadA.start();
    }

}

Ответы [ 2 ]

5 голосов
/ 27 августа 2010

Ваши потоки каждый ждут и уведомляют отдельные объекты, поэтому они вообще не общаются друг с другом. Если вы хотите, чтобы они эффективно выпускали друг друга, им потребуется общий монитор для синхронизации, ожидания и уведомления.

Он «работает», когда вы указываете тайм-аут, потому что он фактически превращает ожидающий вызов в неактивный вызов ... все же на самом деле ничего не ждет и не извещает с пользой, потому что два потока все еще имеют дело с отдельными мониторами.

0 голосов
/ 27 августа 2010

ваши объекты не работают на одном мониторе.

вам нужно либо переместить wait () и notify () в один и тот же объект, например: http://www.java -samples.com / showtutorial.php? Tutorialid = 306

или вы можете уведомить целевой объект: http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ315_016.htm

, когда вы установите ожидание (100).Вы устанавливаете тайм-аут.и определенно он проснется через 100 мс.

...