Tsuki丶 2021-07-26 15:47 采纳率: 0%
浏览 41

Java多线程中等待唤醒机制, 资源中的同步函数中添加 else 代码块时输出异常?

最近在学习java多线程中的等待唤醒机制, 如果操作资源的同步函数中添加了else代码块, 输出就会变得异常, 代码如下

// 资源
class Resource {
    private String name;

    private String sex;

    private boolean isExists = false; // 是否已有值

    public synchronized void set(String name, String sex) {
        if(isExists) {
            try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); }
        } else {  // 这里和 print() 方法中 如果不加else, 输出就是mike 和 丽丽 间隔输出, 如果添加, 就会有很多不间隔, 输出一大串丽丽或者mike 
            this.name = name;
            this.sex = sex;
            isExists = true;
            this.notify();
        }
    }

    public synchronized void print() {
        if(!isExists) {
            try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); }
        } else { // 如果不加else, 输出就是mike 和 丽丽 间隔输出, 如果添加, 就会有很多不间隔, 输出一大串丽丽或者mike
            System.out.println(this.name + "." + this.sex);
            isExists = false;
            this.notify();
        }
    }
}

// 赋值
class Input implements Runnable{

    private final Resource r;

    Input(Resource r) {
        this.r = r;
    }

    boolean flag = false; // 模拟赋值切换的

    @Override
    public void run() {
        for(;;) {
            if (flag) {
                r.set("mike", "man");
            } else {
                r.set("丽丽", "女女");
            }
            flag = !flag;
        }
    }
}

// 取值
class Output implements Runnable {

    private final Resource r;

    Output(Resource r) {
        this.r = r;
    }

    @Override
    public void run() {
        for(;;) {
            r.print();
        }
    }
}

public class ResourceDemo {
    public static void main(String[] args) {

        Resource r = new Resource();

        Input in = new Input(r);
        Output out = new Output(r);

        Thread t1 = new Thread(in);
        Thread t2 = new Thread(out);

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

正常输出结果: (mike和丽丽间隔输出)
丽丽.女女
mike.man
丽丽.女女
mike.man
丽丽.女女

不正常输出结果(无间隔输出):
mike.man
mike.man
mike.man
mike.man
mike.man
丽丽.女女
丽丽.女女

  • 写回答

3条回答 默认 最新

  • 关注

    把this.notify();改为this.notifyAll();试试。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月26日

悬赏问题

  • ¥100 java ee ssm项目 悬赏,感兴趣直接联系我
  • ¥15 微软账户问题不小心注销了好像
  • ¥15 x264库中预测模式字IPM、运动向量差MVD、量化后的DCT系数的位置
  • ¥15 curl 命令调用正常,程序调用报 java.net.ConnectException: connection refused
  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥15 使用百度地图api 位置函数报错?
  • ¥15 metamask如何添加TRON自定义网络
  • ¥66 关于川崎机器人调速问题
  • ¥15 winFrom界面无法打开
  • ¥30 crossover21 ARM64版本安装软件问题