使用wait、notity注意事项


等待/通知机制

        等待/通知的相关方法是任意Java对象都具备的,因为这些方法被定义在所有对象的超类 java.lang.Object上,方法如下:
        1.notify:通知一个在对象上等待的线程,使其从main()方法返回,而返回的前提是该线程获取到了对象的锁。
        2.notifyAll:通知所有在等待该对象的线程。
        3.wait():调用该方法的线程进入WAITING状态,只有等待其他线程的通知或者被中断,才会返回。需要注意调用wait方法后,会释放对象的锁。

private Object object = new Object();

    public static void main(String[] args) throws InterruptedException {
        new test01().print();
    }

    public void print() throws InterruptedException {
        new Thread(() -> {
            synchronized (object) {
                System.out.printf(Thread.currentThread().getName(), "1111");

                try {
                    /**
                     * wait()释放锁资源 同时会阻塞线程
                     * wait()、notify()结合synchronized
                     */
                    object.wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.printf(Thread.currentThread().getName(), "0001");
            }

        }).start();
        try {

            Thread.sleep(3000);
            synchronized (object) {
                object.notify();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 通过wait、notity实现生产者和消费者模型

          可以协调生产者和消费者的速度差异,不需要强制二者速率一致。

/**
     * 共享对象
     */
    class Gao {
        public String name;
        private char sex;
        /**
         * flag false 默认false
         * false 输入线程输出值 输出线程拿到锁释放锁
         * true 输出线程输出值 输入线程拿到锁释放锁
         */
        public Boolean flag = false;
    }

    /**
     * 输入线程
     */
    class InputThread extends Thread {
        private Gao gao;

        public InputThread(Gao gao) {
            this.gao = gao;
        }

        @Override
        public void run() {
            int count = 0;
            while (true) {
                //线程安全  给共享全局对象上锁
                synchronized (gao) {
                    //如果gao.flag==true 输入的资源主动释放锁
                    if(gao.flag){
                        try {
                            gao.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    if (count == 0) {
                        gao.name = "高";
                        gao.sex = '男';
                    } else {
                        gao.name = "gao";
                        gao.sex = '女';
                    }
                    gao.flag = true;
                    //唤醒阻塞线程
                    gao.notify();
                }
                count = (count + 1) % 2;
            }
        }
    }

    /**
     * 输出线程
     */
    class OutputThread extends Thread {
        private Gao gao;

        public OutputThread(Gao gao) {
            this.gao = gao;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (gao) {
                    //线程安全  给共享全局对象上锁  出现情况:输出线程会一直拿到锁对象,没有释放
                    //解决方法 wait() 如果 gao.flag==false 输出的资源主动释放锁
                    if(!gao.flag){
                        try{
                            gao.wait();
                        }catch (Exception e){

                        }
                    }
                    System.out.println(gao.name + "," + gao.sex);
                    gao.flag = false;
                    gao.notify();
                }
            }
        }
    }

    public static void main(String[] args) {

        new Thread01().print();
    }

    public void print() {
        //全局对象
        Gao gao = new Gao();
        //输入线程
        InputThread inputThread = new InputThread(gao);
        //输出线程
        OutputThread outputThread = new OutputThread(gao);
        inputThread.start();
        outputThread.start();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值