开发中有这样一个需求背景: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)方法;


版权声明:本文为xc_nostalgia原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xc_nostalgia/article/details/115404409