java对象的wait方法和notify方法的使用

本文介绍了如何在Java中使用wait、notify方法实现线程间的同步,通过一个示例展示了消费者和生产者线程如何协调工作,确保线程安全。关键点包括:对同一对象调用wait和notify方法,避免中途改变对象引用,确保正确释放锁。
摘要由CSDN通过智能技术生成

开发中有这样一个需求背景:controller有两个接口(线程)A、(线程)B。页面上需要同时调用这两个接口,这两个接口里都公用一个静态常量对象,要求接口B返回之前要等接口A对静态常量对象进行某些操作完才能返回。

解决方法:这时静态常量对象的wait方法和notify方法就可以上场了。

synchronized 用法参考https://blog.csdn.net/luoweifu/article/details/46613015

详细:

1.void notify()

          唤醒在此对象监视器上等待的单个线程。

 void notifyAll()

          唤醒在此对象监视器上等待的所有线程。

 void wait()

          在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

2.使用这两个方法时,我们需要先有一个需要上锁的对象,配合synchronize使用
3.wait被执行后,锁自动被释放
notify被执行后,锁不会自动释放,必须执行完notify)方法所在的synchronized代码块后才释放

demo(可能和开头的需求背景不同,主要是能表达那个意思就行):

import org.springframework.beans.BeanUtils;
public class MyTest{
   private static Money money = new Money();

    public static void main(String[] args) {

        //消费者线程
        new Thread() {
            @Override
            public void run() {
                System.out.println("消费者:老板,一份湿炒牛河。");
                try {
                    Thread.sleep(1000);
                    synchronized (money) {
//                        obj.wait(10*1000);//可以设置最大等待时长。如果超过该时间就不等了,继续往后执行,在这时间内如果收到notify()或者notifyAll()就立即恢复往后执行
                        money.wait();//一直等,等到死那种
                    }
                    //唤醒后执行
                    Thread.sleep(1000);
                    System.out.println("消费者:嗯,好吃。");
                    System.out.println("有钱" + money.getMoney() + "元可以结账了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }.start();

        //老板线程
        new Thread() {
            @Override
            public void run() {

                System.out.println("老板:好嘞,您稍等。");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("老板:湿炒牛河,您慢用。");
                Money newMoney = new Money();
                newMoney.setMoney(100);
                // 模拟数据更改
//                money = newMoney;//特别注意这里,money = newMoney相当于改变了obj引用的对象,下面的synchronized (money)其实是对另一个对象加了锁,
//                并不是消费者那里加锁的那个全局常量money,这样会 导致消费者那里一直等待,正确方式应该用下面的BeanUtils.copyProperties(newMoney, money);;进行原对象的属性赋值操作
                BeanUtils.copyProperties(newMoney, money);
                //唤醒消费者
                synchronized (money) {
                    money.notifyAll();
                }
            }
        }.start();
    }

}

注意点:

   1,一定要是对同一个对象调用wait方法和notify方法

   2, 中途不得修改对象的引用地址,可以用BeanUtils.copyProperties(newMoney, money)方法;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值