Object#wait()与Object#wait(long)的区别
例子
例1 最基础的等待-通知
下面一个例子,一个线程"waiting"在同步代码块调用了Object#wait()方法,另一个线程"timedWaiting"调用了Object#wait(3000)等待3000ms,主线程sleep 5000ms后唤醒所有线程。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j; /**
* @see Object#wait(long) 等待对应的毫秒数(不为0)或者被唤醒,执行后续代码
* @see Object#wait() 只有被唤醒(底层源码调用wait 0 ms)才能执行后续代码
* @author rhyme
* @date 2020/5/30 11:38
*/
@Slf4j
public class ObjectWaitMain {
private static final Object lock = new Object(); private static final Runnable waiting =
() -> {
synchronized (lock) {
try {
log.info("Thread: {}, will Object#wait()", Thread.currentThread().getName());
lock.wait();
log.info("Thread: {} is notified.", Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; private static final Runnable timedWaiting =
() -> {
synchronized (lock) {
try {
log.info(
"Thread: {}, will be notified or wait 3000 milliseconds.",
Thread.currentThread().getName());
lock.wait(3000);
log.info(
"Thread: {}, after being notified or wait 3000 milliseconds.",
Thread.currentThread().getName()); } catch (InterruptedException e) {
e.printStackTrace();
}
}
}; public static void main(String[] args) throws InterruptedException { CompletableFuture.allOf(
CompletableFuture.runAsync(waiting), CompletableFuture.runAsync(timedWaiting)); // 主线程sleep5000ms,当3000ms后"timedWaiting"线程执行"wait(3000)"后的代码块
// 如果"timedWaiting"线程在3000ms被notify,那么会立即执行后续代码,不会wait 3000ms
TimeUnit.MILLISECONDS.sleep(5000); synchronized (lock) {
log.info("main will notifyAll waiting thread.");
lock.notifyAll();
}
log.info("main end.");
}
}
执行结果:

例2 Object#wait(long)的参数大于0与等于0
测试类代码
/**
* @author rhyme
* @date 2020/5/31 0:43
*/
@Slf4j
public class ThreadPoolExecutorTest {
private ThreadPoolExecutor threadPoolExecutor; @Before
public void initializeThreadPoolExecutor() {
threadPoolExecutor =
new ThreadPoolExecutor(4, 8, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(4));
} @After
public void teardown() throws InterruptedException {
threadPoolExecutor.shutdown(); TimeUnit.SECONDS.sleep(2);
threadPoolExecutor = null;
}
大于0
/**
* 当 {@link Object#wait(long)}的参数是大于0, 线程wait对象的毫秒数后, 不需被唤醒, 就可再次获取锁执行wait后续代码
* @see Object#wait(long)
*/
@Test
public void synchronizedTimedWaitingTest() {
Runnable timedWaiting =
() -> {
synchronized (this) {
while (true) {
try {
log.info("before Object#wait(1);");
this.wait(1);
log.info("after Object#wait(1);");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}; threadPoolExecutor.execute(timedWaiting);
}
执行结果:

等于0或Object#wait()
/**
* 当 {@link Object#wait(long)}的参数是0, 线程只能是被唤醒后, 才能再次获取锁执行wait后续代码
* @see Object#wait()
*/
@Test
public void synchronizedWaitingTest() {
Runnable timedWaiting =
() -> {
synchronized (this) {
while (true) {
try {
log.info("before Object#wait(0);");
// 与"this.wait()"等价
this.wait(0);
log.info("after Object#wait(0);");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}; threadPoolExecutor.execute(timedWaiting);
}
执行结果, 该线程一直wait, 线程池关闭结束, UT结束:

总结
Object#wait(long) 等待对应的毫秒数后(不为0)或者在等待过程中被唤醒后,就能再次获取锁执行wait后面代码;
Object#wait() 只有被唤醒后(底层源码调用wait 0 ms)才能再次获取锁执行wait后面代码。
源码如下:
public final void wait() throws InterruptedException {
wait(0);
}
public final native void wait(long timeout) throws InterruptedException;
Object#wait()与Object#wait(long)的区别的更多相关文章
- JavaScript中in操作符(for..in)、Object.keys()和Object.getOwnPropertyNames()的区别
ECMAScript将对象的属性分为两种:数据属性和访问器属性.每一种属性内部都有一些特性,这里我们只关注对象属性的[[Enumerable]]特征,它表示是否通过 for-in 循环返回属性,也可以 ...
- Java中的Object、T(泛型)、?区别
因为最近重新看了泛型,又看了些反射,导致我对Object.T(以下代指泛型).?产生了疑惑. 我们先来试着理解一下Object类,学习Java的应该都知道Object是所有类的父类,注意:那么这就意味 ...
- [转] JavaScript中in操作符(for..in)、Object.keys()和Object.getOwnPropertyNames()的区别
ECMAScript将对象的属性分为两种:数据属性和访问器属性.每一种属性内部都有一些特性,这里我们只关注对象属性的[[Enumerable]]特征,它表示是否通过 for-in 循环返回属性,也可以 ...
- Java不定参数Object… obj 和 Object[] 的区别
Java不定参数Object… obj 和 Object[] 的区别 简述: java中方法重载可以实现参数不同自动匹配对应方法.但现实中也存在这种问题.普通传参对于形如下面的方法,却显得臃肿而失优雅 ...
- instanceof和isInstance(Object obj) 和isAssignableFrom(Class cls)的区别和联系
instanceof和isInstance(Object obj) 和isAssignableFrom(Class cls)的区别和联系 编程的时候可能会遇到一个不知道它属于哪个类的 ...
- or in 、Object.keys()以及Object.getOwnPropertyNames有什么区别?
or in .Object.keys()以及Object.getOwnPropertyNames的区别 var obj= Object.create(parent, { b: { value: 2, ...
- host Object和native Object的区别
Native Object: JavaScript语言提供的不依赖于执行宿主的对象,其中一些是内建对象,如:Global.Math:一些是在脚本运行环境中创建来使用的,如:Array.Boolean. ...
- 小tips:JS之for in、Object.keys()和Object.getOwnPropertyNames()的区别
for..in循环 使用for..in循环时,返回的是所有能够通过对象访问的.可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例.这里需要注意的是使用for-in返回的属性因各个浏览器厂 ...
- typeof 和 Object.prototype.toString.call 数据类型判断的区别
使用 typeof 来判断数据类型,只能区分基本类型,即 “number”,”string”,”undefined”,”boolean”,”object” 五种. 但 Object.prototype ...
随机推荐
- MongoDB入门三
MongoDB字段问题 增删查改操作 删除一列操作db.RiderReaTimePositon.update({},{$unset:{'CreateTime':''}},false,true)db. ...
- 新手安装配置git简洁教程
第一步,下载安装git 打开 [git官网] https://git-scm.com/,下载git对应操作系统的版本. 所有东西下载慢的话就可以去找镜像!官网下载太慢,我们可以使用淘宝镜像下载:htt ...
- 如何判断一个String字符串不为空或这不为空字符串
如何判断一个String字符串不为空或这不为空字符串 转载兵哥LOVE坤 最后发布于2018-07-27 00:00:05 阅读数 5144 收藏 展开 1.校验不为空: String str ...
- 二.drf之使用序列化编写视图
总结:两功能序列化: a.拿到queryset --->idc = Idc.objects.all() b.将queryset给序列化成类---->serializer = IdcSeri ...
- Tomcat的介绍
Tomcat简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选. 支持Se ...
- java语言基础(二)_IDEA_方法
IDEA使用 项目结构: 所有代码放置在src文件夹内 新建包:在src文件夹上,右键新建包.包的命名:英文小写.数字.英文句点. 例如:使用公司域名倒写,如cn.itcast.day04.demo0 ...
- java架构-一些设计上的基本常识
最近给团队新人讲了一些设计上的常识,可能会对其它的新人也有些帮助, 把暂时想到的几条,先记在这里. 1.API与SPI分离 框架或组件通常有两类客户,一个是使用者,一个是扩展者. API(Applic ...
- 每日一题 - 剑指 Offer 34. 二叉树中和为某一值的路径
题目信息 时间: 2019-06-27 题目链接:Leetcode tag:深度优先搜索 回溯法 难易程度:中等 题目描述: 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径.从 ...
- 主流App自动化测试框架对比
1.主流App自动化测试框架对比 2.Appium自动化测试框架 官方网址:http://appium.io/ 跨架构:支持原生.混合以及web移动应用 跨平台:Android & I ...
- jira仪表盘的建立与共享
一般在项目测试阶段,可以通过jira仪表盘清晰的展示bug的各个状态的数量,各个开发人员的bug数量. 有效督促开发解决问题. 也为测试日报提供了良好的数据支持,减少人工统计的工作量. 1.建议筛选器 ...