java - 在调用 wait 和 notification 之后,我尝试从主线程加入两个线程

标签 java multithreading

首先,我尝试定义一个包含2个同步方法的类,第一个包含wait()调用,第二个包含notify()调用。

 class Xa {
 public synchronized void printX() {
    try {
        wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("XXX");
}

public synchronized void notifyX() {
    System.out.println("111");
    notify();
}
}

然后我尝试在main中创建两个线程,第一个线程调用Xa类的对象的printX()方法,第二个线程调用同一对象的notifyX()方法,最后是main线程连接两个线程。

我用 for 循环重复这个场景

public class TryQ {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    Thread t1 = null;
    Thread t2 = null;
    for(int i=1 ; i<=100; i++) {
        Xa x = new Xa();

        t1 = new Thread() {
            @Override
            public void run() {
                x.printX();
            }
        };

        t2 = new Thread() {
            @Override
            public void run() {
                x.notifyX();
            }
        };

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

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

问题是,如果没有加入,第一个和第二个线程都会准确打印 100 次,但是当我尝试通过主线程加入它们时,我最多有 2 或 3 行输出......并且程序仍在运行!

为什么?

最佳答案

无论您是否使用join,问题都存在。

问题是,如果t2先执行notifyX

public synchronized void notifyX() {
    System.out.println("111");
    notify();
}

然后t1调用printXt1将永远被阻塞!

public synchronized void printX() {
    try {
        wait();   <--- since t2 has finished, t1 will get stuck here!
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("XXX");
}

区别在于:

  • 如果没有 join,尽管第一个 t1 被卡住,但主线程将创建一个新的 t1 并运行。
  • 使用join,由于第一个t1卡住了,所以join会阻塞主线程,所以不会有下一代.

关于java - 在调用 wait 和 notification 之后,我尝试从主线程加入两个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54375416/

相关文章:

java - 我的 GUI 每次启动时都会弹出两个窗口

java - 代理和纪念品模式

java - 尝试运行 Eclipse 插件时出错

java - 用于访问 Java 库 API 的 PHP 代码

c# - 嵌套线程排队

c# - 异步回调到BackgroundWorker

java - 为什么 "implements Runnable"优先于 "extends Thread"?

java - Android 中的多线程

java - 如何在两条线之间绘制阴影区域

java - 如何使用 Thymeleaf 将 org.joda.time.LocalDateTime 转换或反序列化为毫秒?