聊聊Object类中的wait()和notify()方法
目录
- Object类中的wait()和notify()方法
- 一、特点
- 二、wait()方法的作用
- 三、notify()方法的作用
- 四、wait()和notify()的使用
- object中的wait和notify细节
- wait
- jdk中为啥要规定我们要使用while,而不是if?
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源码:
文章图片
重点看下划线的地方,是不是有些不理解。有个印象我们继续往下看。
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 voidproduce () 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(); }}
我要说的重点是:
文章图片
这样设计真的合理吗?
jdk中为啥要规定我们要使用while,而不是if?
用if为啥不行
1:首先一点我们要搞清楚 wait操作会释放锁这个问题绝对是干货,在工作中绝对会遇到生产者消费者问题,不少程序员会在这个地方踩坑。面试的时候如果考到你这个地方,你能解答出深层原理来。相信面试官会高看你一眼。
2:想想这种情况,当一个生产者线程执行的时候 if number!=0 (此时的number为1 ) 就会发生阻塞 这时候释放出锁 这时候又一个生产者进程进来又会被wait住.然后一个生产者进程进来,消费了一个 但是notifyall 将所有的进程都解开了 。。那两个生产者进程就会直接运行if后面的东西并没有被拉回来重新判断一下。这样就造成了number的值变成2.同理number变成负数也是有可能的(两个消费者进程先进来都堵塞).
【聊聊Object类中的wait()和notify()方法】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- 为什么你的路演总会超时()
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- thinkphp|thinkphp 3.2 如何调用第三方类库
- 使用composer自动加载类文件
- 一个健康的APP和健全的人格大体类似
- 种树郭橐驼传(文言句式+古今异义+词类活用+通假字)
- 归乡-序章(世界伊始,人类无所依靠,我的故事就从这里开始...)
- jQuery插件