java多线程知识点之wait和sleep的区别

Sleep vs Wait

java虚拟机支持多线程开发。在多线程开发中我们可以用线程来启动、执行、结束某些程序控制。在多线程同步开发中我们会接触到两个不同的方法——wait 和 sleep

wait和sleep都是用来控制线程的执行与等待方法。sleep方法是让当前线程延迟一段时间再执行下一句程序指令,wait不会直接让当前线程延迟控制指令执行,而是让线程暂时挂起状态。

一、wait方法:

wait是属于object类的方法,在java中所有类都是继承于object类,当调用wait方法时会将调用方法所处的线程切换到挂起不执行状态。与wait相对应的有notify和notifyAll方法可以让处于wait的object的线程恢复到运行状态。

wait方法必须在synchronized同步所内部调用。当object被调用的时候,java虚拟机(后续称为系统)释放object所对应的synchronized的lock锁,然后再把调用wait的当前线程挂起并添加到wait列表,系统在wait的时候释放lock锁是为了让其他线程能能够synchronized加锁以便于用notify或者notifyAll唤醒wait列表中相应object的线程。

二、sleep方法:

sleep属于Thread线程类的一个静态方法。调用该方法会是当前线程延迟一段时间后执行下一句控制指令,在延迟这段时间内当前线程并没有任何object对象被标记挂起或者其他操作。对于synchronized内的sleep方法,在sleep期间其他线程不能够进入相同synchronized对象内部。

三、小节

1. sleep是线程thread类的静态方法,wait是一个实例化对象的线程控制方法;

2. sleep是thread线程类操作内的方法,wait是任意对象内的方法,范围不同;

3. sleep方法会保留synchronized内的lock锁,wait不会保存synchronized内的锁;

4. 对于synchonized内部执行wait在不执行线程期间不会影响其他线程进入相同的synchronized同步块,而sleep则不允许在sleep期间其他线程进入synchronized内。

=============================================================

# 以上内容来自文章:

http://www.differencebetween.net/technology/software-technology/difference-between-sleep-and-wait/

的部分翻译

=============================================================

在多线程同于应用上的最大区别就是wait可以释放synchronized中的锁,而sleep不会释放。

接下来我们用demo来演示一下这个特性

一、SleepDemo

SleepDemo通过两个线程,SleepThread线程会在synchronized执行中sleep 3秒钟,ReadThread线程直接运行,但是会在运行中经过synchronized代码块。由于Thread.sleep在延迟执行时不会释放synchronized持有的锁,所以ReadThread必须等待SleepThread退出锁后继续运行,具体代码如下

import java.lang.Thread;public class SleepDemo {public static void main(String args[]) {Object lock = new Object();SleepThread t1 = new SleepThread(lock);t1.start();// sleep to ensure thread of t1 start before t2try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}ReadThread t2 = new ReadThread(lock);t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}}
}class SleepThread extends Thread {Object lock = new Object();public SleepThread(Object lock) {this.lock = lock;}@Overridepublic void run() {System.out.println("SleepThread before synchronized");synchronized (lock) {System.out.println("SleepThread enter synchronized");System.out.println("SleepThread before sleep");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("SleepThread after sleep");System.out.println("SleepThread exit synchronized");}System.out.println("SleepThread after synchronized");}
}class ReadThread extends Thread {Object lock = new Object();public ReadThread(Object lock) {this.lock = lock;}@Overridepublic void run() {System.out.println("ReadThread before synchronized");synchronized (lock) {System.out.println("ReadThread enter synchronized");System.out.println("ReadThread exit synchronized");}System.out.println("ReadThread after synchronized");}
}

编译:

$ javac SleepDemo.java

$ java SleepDemo

SleepThread before synchronized

SleepThread enter synchronized

SleepThread before sleep

ReadThread before synchronized

SleepThread after sleep

SleepThread exit synchronized

SleepThread after synchronized

ReadThread enter synchronized

ReadThread exit synchronized

ReadThread after synchronized

ReadThread准备进入synchronized块时由于锁被SleepThread的synchronized持有,必须等待sleep结束后退出synchronized块才能往下继续执行。

二、WaitDemo

SleepDemo通过两个线程,WaitThread线程会在synchronized执行中sleep 3秒钟,ReadThread线程直接运行,但是会在运行中经过synchronized代码块。由于Object.wait在被挂起时释放synchronized持有的锁,ReadThread执行synchronized代码时如果WaitThead已经处于wait状态时能够继续进入synchronized代码,不需要等待,具体代码如下

import java.lang.Thread;public class WaitDemo {public static void main(String args[]) {Object lock = new Object();WaitThread t1 = new WaitThread(lock);t1.start();// sleep to ensure thread of t1 start before t2try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}ReadThread t2 = new ReadThread(lock);t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}}
}class WaitThread extends Thread {Object lock = new Object();public WaitThread(Object lock) {this.lock = lock;}@Overridepublic void run() {System.out.println("WaitThread before synchronized");synchronized (lock) {System.out.println("WaitThread enter synchronized");System.out.println("WaitThread before wait");try {lock.wait(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("WaitThread after wait");System.out.println("WaitThread exit synchronized");}System.out.println("WaitThread after synchronized");}
}class ReadThread extends Thread {Object lock = new Object();public ReadThread(Object lock) {this.lock = lock;}@Overridepublic void run() {System.out.println("ReadThread before synchronized");synchronized (lock) {System.out.println("ReadThread enter synchronized");System.out.println("ReadThread exit synchronized");}System.out.println("ReadThread after synchronized");}
}

编译运行

$ javac WaitDemo.java

$ java WaitDemo

WaitThread before synchronized

WaitThread enter synchronized

WaitThread before wait

ReadThread before synchronized

ReadThread enter synchronized

ReadThread exit synchronized

ReadThread after synchronized

WaitThread after wait

WaitThread exit synchronized

WaitThread after synchronized

可以看看到synchronized调用wait后不会影响其他synchronized锁的代码。

java多线程知识点之wait和sleep的区别相关推荐

  1. JAVA 多线程知识点

    线程创建的方式 继承Thread类,重写run方法 实现Runnable接口 实现Callable接口 获取线程ID和线程名称 Thread子类中调用this.getId()或者this.getNam ...

  2. Java多线程知识点整理(线程池)

    2019独角兽企业重金招聘Python工程师标准>>> 1.线程池的使用 线程池一般配合队列一起工作,是线程池限制并发处理任务的数量.然后设置队列的大小,当任务超过队列大小时,通过一 ...

  3. java多线程知识点总结

    1.线程调度知识:线程类Thread的了解,几个thread的方法.thread.sleep(),thread.join().(调用join方法的那个线程会立刻执行). object.wait()方法 ...

  4. Java多线程知识点整理(Lock锁)

    2019独角兽企业重金招聘Python工程师标准>>> 1.Lock的使用 private Lock lock = new ReentrantLock();public void t ...

  5. Java多线程学习十三:synchronized 和 Lock 区别以及孰优孰劣,如何选择?

    synchronized 和 Lock 的异同点,以及该如何选择. 相同点 synchronized 和 Lock 的相同点非常多,我们这里重点讲解 3 个比较大的相同点 ABC. A:synchro ...

  6. Java多线程 - Runnable接口和Callable接口的区别

    文章目录 1. Runnable接口实例 2. Callable接口原理 3. Callnable接口实例 4. FutureTask是什么? 5. 线程池中 submit() 和 execute() ...

  7. Java多线程:synchronized | Volatile 和Lock和ReadWriteLock多方位剖析(一)

    前言 本文站在多线程初中级学习者的角度,较为全面系统的带你一起了解多线程与锁相关的知识点.带你一起解开与锁相关的各种概念.用法.利弊等.比如:synchronized.Volatile.Lock.Re ...

  8. 【26天高效学习Java编程】Day19:60 多个实例讲解,彻底搞懂Java 多线程 【可查阅,可复习,可面试】

    本专栏将从基础开始,循序渐进,由浅入深讲解Java的基本使用,希望大家都能够从中有所收获,也请大家多多支持. 专栏地址:26天高效学习Java编程 相关软件地址:软件地址 所有代码地址:代码地址 如果 ...

  9. java多线程生命周期

    在java多线程中,没有主次线程的区别,只要有线程还在运行,进程就不会结束 import java.util.Arrays; import java.util.HashSet; import java ...

  10. java 多线程 并发 面试题_最常见的15个Java多线程,并发面试问题

    假设你有三个线程T1,T2,T3.你如何能保证线程T2在线程T1后运行,T3在T2后运行 这个线程面试问题大多是在第一轮或电话筛选轮次中会被问到的,这个多线程问题的目的是检查候选人对"joi ...

最新文章

  1. 访问 Microsoft SQL Server 元数据的三种
  2. SQL SERVER中Datetime时间的范围与.net的DateTime对象的区别
  3. dedecms的特性-----不完整
  4. 扩展springmvc组件——当页面跳转时,需要在Controller里面创建一个空方法去跳转或者是创建一个配置类  ||日期格式化说明||自定义格式化器||消息转化器扩展fastjson
  5. IOS开发之sqlite封装
  6. 一生只有43年,喜欢泡妹打架,却凭借一篇文章震惊世界,跻身一流数学家
  7. 【洛谷比赛】你的名字。
  8. Ubunt 配置网络服务
  9. python怎么做回归分析_如何在Python中进行二维回归分析?
  10. 信息学奥赛C++语言: 统计闰年
  11. 存储过程+调用存储过程+无/带参的存储过程+in参数+out参数+int out参数+为参数设置默认值...
  12. mybatis获取自增主键的值
  13. 随机森林进行特征选择
  14. Ubuntu16.04安装为知笔记(WizNote)
  15. Android之四大组件、六大布局、五大存储
  16. Stylus入门教程--实例(1)
  17. API是什么?api的意思!!!
  18. 【使用QGIS入库将shp数据导入postgis、postgres数据库】
  19. 记录 免费高清视频下载网站
  20. Android桌面图标布局,android安装运行launcher并修改桌面图标

热门文章

  1. 算法萌新如何学好动态规划(三)
  2. 计算机图形学完整笔记(二):光栅图形学算法
  3. html5 mature,Deep Dive into “HTML5”
  4. JSONP原理及使用
  5. CentOS安装CAS 5.3.4服务端
  6. js知识梳理1:理解对象的属性特性
  7. angularJs模版注入的两种方式
  8. Operation not applicable
  9. 开博第一篇:一个关于正则表达式相关的问题
  10. WEB2.0 XHTML代码规范