服务器之家

服务器之家 > 正文

聊聊Object类中的wait()和notify()方法

时间:2022-01-20 00:56     来源/作者:百了江

Object类中的wait()和notify()方法

一、特点

wait()和notify()方法并不是线程对象的方法,是Java中任何一个Java对象都有的方法,并不特殊。

二、wait()方法的作用

Object obj = new Object();
obj.wait();

表示:obj.wait();方法的调用,会让“当前线程(正在obj对象上活动的线程)”进入等待状态。

三、notify()方法的作用

Object obj = new Object();
obj.notify();

表示:唤醒正在obj对象上等待的线程。

补充:

Object obj = new Object();
obj.notifyAll();

表示:唤醒正在obj对象上等待的所有线程。

四、wait()和notify()的使用

wait()和notify()方法都是建立在synchronized线程同步的基础之上

重点

obj.wait()方法会让正在obj对象上活动的当前线程进入等待状态,并且释放之前占有的obj对象的锁。

obj.notify()方法只会通知,不会释放之前占有的obj对象的锁。

 

object中的wait和notify细节

wait

jdk源码:

聊聊Object类中的wait()和notify()方法

重点看下划线的地方,是不是有些不理解。有个印象我们继续往下看。

public class resourse {
  private Integer number = 0 ;
  /**
   * 用if为啥不行
   * 1:首先一点我们要搞清楚 wait操作会释放锁
   * 2:想想这种情况,当一个生产者线程执行的时候 if number!=0 (此时的number为1 ) 就会发生阻塞 这时候
   * 释放出锁 这时候又一个生产者进程进来又会被wait住.然后一个生产者进程进来,消费了一个 但是notifyall 将所有的进程
   * 都解开了 。。那两个生产者进程就会直接运行if后面的东西并没有被拉回来重新判断一下。这样就造成了number的值变成2.同理number
   * 变成负数也是有可能的(两个消费者进程先进来都堵塞).
   *
   *
   *
   *
   * @throws Exception
   */
  public synchronized void  produce () throws Exception
  {
//        判断  这里用while 用if多与两个线程容易出错
//        不等于0就要等待消费者消费完
       if(number!=0)
       {
           this.wait();
       }
//         干活
      number++;
      System.out.println(Thread.currentThread().getName() + "的资源数为:" + number.toString());
//        释放
      this.notifyAll();
  }
//wait操作会释放锁
  public synchronized void consumer () throws Exception
  {
      //    等于零就要等待生产者生产
      if (number == 0)
      {
          this.wait();
      }
//        消费
      number--;
      System.out.println(Thread.currentThread().getName() + "的资源数为:" + number.toString());
//        释放
      this.notifyAll();
  }
}

调用者。这里开启了两个生产者和两个消费者线程。生产者线程都执行100次的produce,消费者线程都执行100次的consumer

public class main {
  public static void main (String[] args) {
      resourse resourse = new resourse();
          new Thread(()->{
              try{
                  for (int i=0 ; i<100;i++)
                  resourse.produce();
              }catch (Exception e)
              {
                  e.printStackTrace();
              }
          }).start();
      new Thread(()->{
          try{
              for (int i=0 ; i<100;i++)
              resourse.produce();
          }catch (Exception e)
          {
              e.printStackTrace();
          }
      }).start();
      new Thread(()->{
          try{
              for (int i=0 ; i<100;i++)
                  resourse.consumer();
          }catch (Exception e)
          {
              e.printStackTrace();
          }
      }).start();
      new Thread(()->{
          try{
              for (int i=0 ; i<100;i++)
              resourse.consumer();
          }catch (Exception e)
          {
              e.printStackTrace();
          }
      }).start();
  }
}

我要说的重点是:

聊聊Object类中的wait()和notify()方法

这样设计真的合理吗?

jdk中为啥要规定我们要使用while,而不是if?

用if为啥不行

1:首先一点我们要搞清楚 wait操作会释放锁

2:想想这种情况,当一个生产者线程执行的时候 if number!=0 (此时的number为1 ) 就会发生阻塞 这时候释放出锁 这时候又一个生产者进程进来又会被wait住.然后一个生产者进程进来,消费了一个 但是notifyall 将所有的进程都解开了 。。那两个生产者进程就会直接运行if后面的东西并没有被拉回来重新判断一下。这样就造成了number的值变成2.同理number变成负数也是有可能的(两个消费者进程先进来都堵塞).

这个问题绝对是干货,在工作中绝对会遇到生产者消费者问题,不少程序员会在这个地方踩坑。面试的时候如果考到你这个地方,你能解答出深层原理来。相信面试官会高看你一眼。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_44705164/article/details/112758403

标签:

相关文章

热门资讯

蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部