java中wait和sleep的区别

在本篇文章中,我们将会讨论一下java中wait()和sleep()方法的区别。并讨论一下怎么使用这两个方法。

Wait和sleep的区别

wait() 是Object中定义的native方法:

public final native void wait(long timeout) throws InterruptedException;

所以每一个类的实例都可以调用这个方法。wait()只能在synchronized block中调用。它会释放synchronized时加在object上的锁。

sleep()是定义Thread中的native静态类方法:

public static native void sleep(long millis) throws InterruptedException;

所以Thread.sleep()可以在任何情况下调用。Thread.sleep()将会暂停当前线程,并且不会释放任何锁资源。

我们先看一下一个简单的wait使用:

@Slf4j
public class WaitUsage { private static Object LOCK = new Object(); public static void WaitExample() throws InterruptedException {
synchronized (LOCK) {
LOCK.wait(1000);
log.info("Object '" + LOCK + "' is woken after" +
" waiting for 1 second");
}
}
}

再看一下sleep的使用:

@Slf4j
public class SleepUsage { public static void sleepExample() throws InterruptedException {
Thread.sleep(1000);
log.info(
"Thread '" + Thread.currentThread().getName() +
"' is woken after sleeping for 1 second");
}
}

唤醒wait和sleep

sleep()方法自带sleep时间,时间过后,Thread会自动被唤醒。

或者可以通过调用interrupt()方法来中断。

相比而言wait的唤醒会比较复杂,我们需要调用notify() 和 notifyAll()方法来唤醒等待在特定wait object上的线程。

notify()会根据线程调度的机制选择一个线程来唤醒,而notifyAll()会唤醒所有等待的线程,由这些线程重新争夺资源锁。

wait,notity通常用在生产者和消费者情形,我们看下怎么使用:

@Slf4j
public class WaitNotifyUsage { private int count =0; public void produceMessage() throws InterruptedException { while(true) {
synchronized (this) {
while (count == 5) {
log.info("count == 5 , wait ....");
wait();
}
count++;
log.info("produce count {}", count);
notify();
}
}
} public void consumeMessage() throws InterruptedException { while (true) {
synchronized (this) {
while (count == 0) {
log.info("count == 0, wait ...");
wait();
}
log.info("consume count {}", count);
count--;
notify();
}
}
}
}

看下怎么调用:

   @Test
public void testWaitNotifyUsage() throws InterruptedException{
WaitNotifyUsage waitNotifyUsage=new WaitNotifyUsage(); ExecutorService executorService=Executors.newFixedThreadPool(4);
executorService.submit(()-> {
try {
waitNotifyUsage.produceMessage();
} catch (InterruptedException e) {
e.printStackTrace();
}
}); executorService.submit(()-> {
try {
waitNotifyUsage.consumeMessage();
} catch (InterruptedException e) {
e.printStackTrace();
}
}); Thread.sleep(50000);
}

本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/wait-sleep

更多教程请参考 flydean的博客

java中wait和sleep的区别的更多相关文章

  1. Java中Set Map List 的区别

    java中set map list的区别: 都是集合接口 简要说明 set --其中的值不允许重复,无序的数据结构 list   --其中的值允许重复,因为其为有序的数据结构 map--成对的数据结构 ...

  2. Java中Comparable和Comparator接口区别分析

    Java中Comparable和Comparator接口区别分析 来源:码农网 | 时间:2015-03-16 10:25:20 | 阅读数:8902 [导读] 本文要来详细分析一下Java中Comp ...

  3. 转:Java中abstract和interface的区别

    转自:Java中abstract和interface的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java ...

  4. Java中this与super的区别【6】

    若有不正之处,请多多谅解并欢迎批评指正,不甚感激.请尊重作者劳动成果: 本文原创作者:pipi-changing本文原创出处:http://www.cnblogs.com/pipi-changing/ ...

  5. Java中堆和栈的区别(转)

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.      Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...

  6. 转:二十一、详细解析Java中抽象类和接口的区别

    转:二十一.详细解析Java中抽象类和接口的区别 http://blog.csdn.net/liujun13579/article/details/7737670 在Java语言中, abstract ...

  7. Java中Long与long的区别(转)

    Java中Long与long的区别(转) [本文转载自:http://www.cnblogs.com/bluestorm/archive/2012/04/22/2464739.html] 转载请联系原 ...

  8. java中堆和堆栈的区别

    java中堆和堆栈的区别(一) 1.栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取 ...

  9. Java中ArrayList与LinkedList的区别

    Java中ArrayList与LinkedList的区别 一般大家都知道ArrayList和LinkedList的区别: 1. ArrayList的实现是基于数组,LinkedList的实现是基于双向 ...

  10. java 标准输出与标准错误 out与 err 区别 用法 联系 java中的out与err区别 System.out和System.err的区别 System.out.println和System.err.println的区别 Java重定向System.out和System.err

    本文关键词: java 标准输出与标准错误    out与 err 区别 用法 联系  java中的out与err区别  System.out和System.err的区别 System.out.pri ...

随机推荐

  1. DOM--选取文档元素

    大多数的客户端JavaScript程序在运行时都是在操作一个或者多个文档元素,而为了操作文档中的元素我们就必须要通过某种途径或者方法获得或者选取这些引用文档元素的Element对象.DOM定义了许多种 ...

  2. javascript 3d网页 示例 ( three.js 初探 七)

    1 完整代码下载 https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ 提取码 3fzt (压缩包名: 2020-4-5-demo.zip) 2 图片展示 3 ...

  3. Python安装MySQL数据库模块

    背景 折腾: [记录]使用Python操作MySQL数据库 的过程中,需要去安装MySQLdb. 下载MySQLdb 去官网: http://pypi.python.org/pypi/MySQL-py ...

  4. Dos 命令启动网卡

    禁用网卡: netsh interface set interface "本地连接" disabled 启用网卡 : netsh interface set interface & ...

  5. jvm入门及理解(三)——运行时数据区(程序计数器+本地方法栈)

    一.内存与线程 内存: 内存是非常重要的系统资源,是硬盘和cpu的中间仓库及桥梁,承载着操作系统和应用程序的实时运行.JVM内存布局规定了JAVA在运行过程中内存申请.分配.管理的策略,保证了JVM的 ...

  6. "文字链接"组件:<h-link> —— 快应用组件库H-UI

     <import name="h-link" src="../Common/ui/h-ui/basic/c_link"></import&g ...

  7. JPA入门例子(采用JPA的hibernate实现版本) --- 会伴随 配置文件:persistence.xml

    JPA入门例子(采用JPA的hibernate实现版本) 分类: j2se2011-03-30 16:09 45838人阅读 评论(9) 收藏 举报 jpahibernate数据库jdbcjava框架 ...

  8. syncronized如何上锁

    上锁,根据操作系统所说的原则,对共享变量上锁,对临界区上锁.谁访问临界资源?就给谁上锁 同步监视器,它上锁的对象. 1.用关键字给方法上锁 2.用synchronized代码块上锁 默认上锁对象:th ...

  9. Python分析数据难吗?某科技大学教授说,很难但有方法就简单

    用python分析数据难吗?某科技大学的教授这样说,很难,但要讲方法,主要是因为并不是掌握了基础,就能用python来做数据分析的. 所谓python的基础,也就是刚入门的python学习者,学习的基 ...

  10. Android 程序代码进行代码混淆

    1.在Eclipse项目包下的project.properties文件中加入proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt ...