wait、notify和notifyAll方法

wait() 方法会使该锁资源释放,然后线程进入等待WAITING状态,进入锁的waitset中,然后等待其他线程对锁资源调用notify方法或notifyAll方法进行唤醒,否则就会进入无限等待。唤醒后会继续执行wait() 后面的代码。

wait(long timeout)wait(long timeout, int nanos) 两个方法差不多,就是对wait方法的过期时间进行限制,如果超过该时间,就将线程放出来进入等待队列继续请求锁资源,然后得到锁资源后继续从wait()方法后面执行。等待过程中线程的状态为TIMED_WAITING,和wait()方法进行区分。

wait和sleep方法进行对比

wait方法首先会释放锁,然后进入一个WAITING(没有timeout参数)或者TIMED_WAITING(有timeout参数)状态,然后等待唤醒或者过期自动唤醒,重新去竞争锁资源。

sleep方法就不会释放锁资源,直接将线程设置进入TIMED_WAITING状态,等待时间过去继续执行后续代码

设计模式-保护性暂停

A ---- > B <------- C

首先会两个线程需要对一个GuardObject 进行存取,首先A会等待C把东西放进去然后A将其取出。

class GuardObjectOld{
private Object value; public synchronized Object getObject(){
while (value == null){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return value;
} public synchronized void setObject(Object o){
this.value = o;
this.notifyAll();
}
}

首先呢两个线程会对同一个GuardObject 对象进行存取。

取线程会调用getObject()方法,然后当value为空会进入wait方法等待存线程放入资源。

存线程调用setObject方法放入资源,然后进行通知waitset中的线程醒过来取资源。

然后可以对其进行增加超时保护

/**
* 增加超时检验
*/
@Slf4j
class GuardObject{
private Object value; public synchronized Object getObject(long timeout){
long startTime = System.currentTimeMillis();
long waitTime = 0;
while (value == null){
if (timeout - waitTime <= 0){
break;
}
try {
// 防止虚假唤醒,然后又要等好几秒
this.wait(timeout - waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
waitTime = System.currentTimeMillis() - startTime;
}
return value;
} public synchronized void setObject(Object o){
this.value = o;
this.notifyAll();
}
}

在上述代码基础上加入了超时保护,首先是记录运行时间waitTime,刚开始为0。

如果过程中没有被其他的线程唤醒,线程会执行wait(2000)方法等待2秒如果没有被唤醒就直接继续执行下面代码,继续循环if语句判断true跳出循环。

如果过程中被其他的线程虚假唤醒了,然后线程就会发现资源还是空,然后会继续循环,等待时间就是设定的timeout时间减去已经等待的时间waittime。

wait、notify和notifyAll方法学习的更多相关文章

  1. 多线程协作wait、notify、notifyAll方法简介理解使用 多线程中篇(十四)

    在锁与监视器中有对wait和notify以及notifyAll进行了简单介绍 所有对象都有一个与之关联的锁与监视器 wait和notify以及notifyAll之所以是Object的方法就是因为任何一 ...

  2. 关于java的wait、notify、notifyAll方法

    wait.notify.notifyAll 遇到的问题 之前开发打印机项目,因为需要使用多线程技术,当时并不怎么理解,一开始随意在方法体内使用wait.notify.notifyAll 方法导致出现了 ...

  3. Java线程和多线程(二)——对象中的wait,notify以及notifyAll方法

    Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notif ...

  4. 【并发编程】Object的wait、notify和notifyAll方法

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 方法简介 wait方法 wait方法是Object类中的 ...

  5. 【Java并发系列02】Object的wait()、notify()、notifyAll()方法使用

    一.前言 对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多. 二.线程安全基本知识 首先应该记住以下基本点,先背下来也无妨: ...

  6. java线程学习之notify方法和notifyAll方法

    notify(通知)方法,会将等待队列中的一个线程取出.比如obj.notify();那么obj的等待队列中就会有一个线程选中并且唤醒,然后被唤醒的队列就会退出等待队列.活跃线程调用等待队列中的线程时 ...

  7. 最简实例说明wait、notify、notifyAll的使用方法

    wait().notify().notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态. 这三个方法最终调用的都是jvm级的native方法.随着jvm运行平台的不同可能有些 ...

  8. 并发编程之二:wait、notify、notifyAll的使用方法

    wait().notify().notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态. public final native void wait(long timeout ...

  9. object的wait()、notify()、notifyAll()、方法和Condition的await()、signal()方法

    wait().notify()和notifyAll()是 Object类 中的方法 从这三个方法的文字描述可以知道以下几点信息: 1)wait().notify()和notifyAll()方法是本地方 ...

随机推荐

  1. 学习Squid(三)

    Squid 缓存服务 1.缓存服务器结束 缓存服务器(cache server),即用来存储(介质为内存及硬盘)用户访问的网页.图片.文件等等信息的专用服务器,这种服务器不仅可以使用户可以最快的得到他 ...

  2. SpringDataJpa备忘录

    单向多对一关系 //产品类型 一的一方 @Entity public class ProductDir { @Id @GeneratedValue private Long id; private S ...

  3. OpenCV - Add Noise的一些方法

    噪声常用有两种:一种椒盐噪声,一种高斯噪声. import numpy as np def pepper_and_salt(src, proportion): """ : ...

  4. 解决引用类型为什么打出的是地址值,又怎么改成输出属性值(toString()底层)

    一丶toString的源码解析: 一丶object的toString的源码解析: 集合中toString源码分析: 小结: 改成输出属性值 在父类中重写toString();方法 快捷键:Alt+In ...

  5. s函数中积分程序更改

    function [sys,x0,str,ts,simStateCompliance] = int_hyo(t,x,u,flag) switch flag, case 0, [sys,x0,str,t ...

  6. 《深入理解ES6》笔记—— JavaScript中的类class(9)

    ES5中的近类结构 ES5以及之前的版本,没有类的概念,但是聪明的JavaScript开发者,为了实现面向对象,创建了特殊的近类结构. ES5中创建类的方法:新建一个构造函数,定义一个方法并且赋值给构 ...

  7. ES6-11学习笔记--let

    新声明方式:let 1.不属于顶层对象 window 2.不允许重复声明 3.不存在变量提升 4.暂时性死区 5.块级作用域   原来var声明: var a = 5; console.log(a); ...

  8. caioj 1001: [视频]实数运算1[水题]

    题意:输入两个实数a和b,输出它们的和 题解:简单题不写题解了-- 代码: #include <cstdio> double a, b; int main() { while (~scan ...

  9. 自己写一个简单的LinkedList

    单链表 推荐阅读:https://www.cnblogs.com/zwtblog/tag/源码/ 哨兵节点: 哨兵节点在树和链表中被广泛用作伪头.伪尾等,通常不保存任何数据. 我们将使用伪头来简化我们 ...

  10. Servlet 3.1学习笔记

    Servlet 3.1学习笔记 参考文档 Servlet 3.1标准 什么是 Servlet ? Servlet 是基于 Java 平台的 Web 组件,由一个容器管理,能够生成动态内容. 什么是 S ...