Многопотоковая связь, почему вывод не гарантируется, хотя используется ожидание и уведомление

1

Я ожидаю выхода в последовательности из 7 100 000 множителей, иногда он показывает, но иногда нет. Я не понял, что пошло не так с использованием ожидания и уведомления.

    package com.facebook.dao;

    public class ManyThreads {

        public static void main(String[] args) {
            // TODO Auto-generated method stub
            targets target = new targets();

            T1 x = new T1(target);
            T2 y = new T2(target);
            T3 z = new T3(target);

            Thread t1 = new Thread(x);
            Thread t2 = new Thread(y);
            Thread t3 = new Thread(z);

            t1.start();
            t2.start();
            t3.start();
        }

    }
   class targets {
        boolean twoFlag = false;
        boolean threeFlag = true;
        boolean fiveFlag = true;
        int i = 7, j = 100, k = 1000;

      public synchronized void twoMul() {
            if (twoFlag) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println(i * 2);
            threeFlag = false;
            twoFlag = true;
            notify();
        }

        public synchronized void threeMul() {

            if (threeFlag) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println(j * 3);
            fiveFlag = false;
            threeFlag = true;
            notify();

        }

        public synchronized void fiveMul() {

            if (fiveFlag) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println(k * 5);
            twoFlag = false;
            fiveFlag = true;
            notify();

        }

    }
   class T1 implements Runnable {
        targets t;
        T1(targets y) {
            this.t = y;
        }

    public void run() {
            for (int i = 0; i < 3; i++) {

                t.twoMul();

            }
        }
    }

    class T2 implements Runnable {
        targets t;

        T2(targets y) {
            this.t = y;
        }

        public void run() {
            for (int i = 0; i < 3; i++) {

                t.threeMul();

            }
        }
    }
   class T3 implements Runnable {
        targets t;
        T3(targets y) {
            this.t = y;
        }

        public void run() {
            for (int i = 0; i < 3; i++) {

                t.fiveMul();

            }
        }
    }

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

Теги:
multithreading

1 ответ

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

notify() уведомляет один из ожидающих потоков. Итак, после того, как задача T1 вызвала notify(), либо T2, либо T3 проснется и продолжит свою задачу.

Обратите внимание, что вы не зацикливаете, чтобы проверить условия. Вы используете, if. Итак, как только перезапуск потока, он выходит из блока if и продолжается.

BTW, даже если это было намерение, оно не соответствует правилам, описанным в документации wait(): могут возникнуть побочные пробуждения, и ожидание должно всегда вызываться внутри цикла и проверять состояние перед выходом из состояние ожидания.

Так

  1. Использование циклы вместо if
  2. Используйте notifyAll() вместо notifyAll() notify()
  • 0
    Thxs много. Я согласен со 2-м пунктом. Но цикл, который я использовал в соответствующем классе, сам. Это работает.
  • 0
    Ничего себе !!! после использования цикла while вместо If всегда получаю точный ответ. Thxs JB Nizet .. Но я действительно не понимаю, почему он не работает с If. Вы можете подробно объяснить, что не так, если GNG
Показать ещё 2 комментария

Ещё вопросы

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