java - 多线程通信为什么使用等待和通知不能保证输出

标签 java multithreading

我期望以 7,100,1000 个乘法器的序列输出,有时显示但有时不显示。我不明白等待和通知的用法出了什么问题。

    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();

            }
        }
    }

我认为我正确地使用了标志,但我想知道哪里出了问题。

最佳答案

notify() 通知等待线程中的一个。因此,在 T1 任务调用 notify() 后,T2 或 T3 将唤醒并继续其任务。

请注意,您并不是在循环检查条件。您正在使用 if。因此,一旦线程重新启动,它就会跳出 if block 并继续。

顺便说一句,即使那是意图,它也不遵循 documentation of wait() 中描述的规则。 : 可能会发生虚假唤醒,并且应始终在循环内调用 wait 并在退出等待状态之前检查条件。

所以

  1. 使用循环代替 if
  2. 使用notifyAll()代替notify()

关于java - 多线程通信为什么使用等待和通知不能保证输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22730006/

相关文章:

java - 是否可以通过在 run() 方法中调用 run() 来启动线程?

java - JPOS 多路复用器上并行多个 ISO8583 请求

java - mutex内部是如何实现的

c - 在子进程中生成随机数

c++ - 在线程之间传递数据的最佳实践是什么?队列、消息或其他?

java - 在带有 JAX-RS 的方法上使用 subPath

java - 使用 Java Streams 获取不包含在同一列表中的结果列表

java - DDL 生成和常规 persistence.xml 设置 (OpenJPA)

java - jQuery 相对 URL 不起作用

java - 通过不同的线程访问变量和 Swing 组件