Java 多线程基础(七)线程休眠 sleep

一、线程休眠 sleep

sleep() 方法定义在Thread.java中,是 static 修饰的静态方法。
sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间;在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待cpu的调度执行。

二、sleep示例

  1. public class SleepTest {
  2. private static Object obj = new Object();
  3. public static void main(String[] args) {
  4. Thread t1 = new MyThread("t1");
  5. t1.start();
  6. }
  7.  
  8. static class MyThread extends Thread{
  9. public MyThread(String name) {
  10. super(name);
  11. }
  12. public void run() {
  13. synchronized (obj) {
  14. try {
  15. for(int i = 0;i < 5;i++) {
  16. System.out.println(Thread.currentThread().getName() + "--" + i);
  17. if (i % 4 == 0)
  18. Thread.sleep(1000);// i能被4整除时,休眠1秒
  19. }
  20. }catch(Exception e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }
  25. }
  26. }
  1. // 运行结果
  2. t1--0
  3. t1--1
  4. t1--2
  5. t1--3
  6. t1--4

说明:

在主线程main中启动线程t1。t1启动之后,当t1中的计算i能被4整除时,t1会通过Thread.sleep(100)休眠100毫秒。

三、sleep(long millis) 与 wait(long timeout)

我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
但是,wait() 会释放对象的同步锁,而 sleep() 则不会释放锁

通过下面的代码,演示 sleep() 不会释放锁的:

  1. public class SleepTest {
  2. private static Object obj = new Object();
  3. public static void main(String[] args) {
  4. Thread t1 = new MyThread("t1");
  5. Thread t2 = new MyThread("t2");
  6. t1.start();
  7. t2.start();
  8. }
  9.  
  10. static class MyThread extends Thread{
  11. public MyThread(String name) {
  12. super(name);
  13. }
  14. public void run() {
  15. synchronized (obj) {
  16. try {
  17. for(int i = 0;i < 5;i++) {
  18. System.out.println(Thread.currentThread().getName() + "--" + i);
                   Thread.sleep(1000);// 休眠1秒
  19. }
  20. }catch(Exception e) {
  21. e.printStackTrace();
  22. }
  23.  
  24. }
  25. }
  26. }
  27. }
  1. // 执行结果
  2. t1--0
  3. t1--1
  4. t1--2
  5. t1--3
  6. t1--4
  7. t2--0
  8. t2--1
  9. t2--2
  10. t2--3
  11. t2--4

说明:

主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.sleep(1000) 进入休眠状态;但是,t2是不会获取CPU执行权的。因为,t1并没有释放“obj所持有的同步锁”!
注意,若我们注释掉 synchronized (obj) 后再次执行该程序,t1和t2是可以相互切换执行的,原因是:在没有同步锁的情况下,当一个线程进入“休眠(阻塞)状态“时,会放弃CPU的执行权,另一个线程就会获取CPU执行权。

通过下面的代码,演示 wait() 会释放锁的:

  1. public class SleepTest {
  2. private static Object obj = new Object();
  3. public static void main(String[] args) {
  4. Thread t1 = new MyThread("t1");
  5. Thread t2 = new MyThread("t2");
  6. t1.start();
  7. t2.start();
  8. }
  9.  
  10. static class MyThread extends Thread{
  11. public MyThread(String name) {
  12. super(name);
  13. }
  14. public void run() {
  15. synchronized (obj) {
  16. try {
  17. for(int i = 0;i < 5;i++) {
  18. System.out.println(Thread.currentThread().getName() + "--" + i);
  19. obj.wait(1000);// 等待1秒
  20. }
  21. }catch(Exception e) {
  22. e.printStackTrace();
  23. }
  24.  
  25. }
  26. }
  27. }
  28. }
  1. // 执行结果
  2. t1--0
  3. t2--0
  4. t1--1
  5. t2--1
  6. t2--2
  7. t1--2
  8. t2--3
  9. t1--3
  10. t2--4
  11. t1--4

说明:

主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,调用 obj.wait(1000) 进入等待状态,释放同步锁;此时,t2会获取CPU执行权的。

Java 多线程基础(七)线程休眠 sleep的更多相关文章

  1. JAVA多线程学习七-线程池

    为什么用线程池 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率 例如: 记创建线程消耗时间T1,执行任务消耗时间T2,销毁线程消耗时间T3 如果T1+T3> ...

  2. Java多线程基础知识总结

    2016-07-18 15:40:51 Java 多线程基础 1. 线程和进程 1.1 进程的概念 进程是表示资源分配的基本单位,又是调度运行的基本单位.例如,用户运行自己的程序,系统就创建一个进程, ...

  3. “全栈2019”Java多线程第七章:等待线程死亡join()方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  4. Java 多线程基础(五)线程同步

    Java 多线程基础(五)线程同步 当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题. 要解决上述多线程并发访问一个资源的安全性问题,Java中提供了同步机制 ...

  5. Java 多线程基础(六)线程等待与唤醒

    Java 多线程基础(六)线程等待与唤醒 遇到这样一个场景,当某线程里面的逻辑需要等待异步处理结果返回后才能继续执行.或者说想要把一个异步的操作封装成一个同步的过程.这里就用到了线程等待唤醒机制. 一 ...

  6. Java 多线程基础(十)interrupt()和线程终止方式

    Java 多线程基础(十)interrupt()和线程终止方式 一.interrupt() 介绍 interrupt() 定义在 Thread 类中,作用是中断本线程. 本线程中断自己是被允许的:其它 ...

  7. Java多线程基础:进程和线程之由来

    转载: Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够 ...

  8. 1、Java多线程基础:进程和线程之由来

    Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...

  9. Java 多线程基础(四)线程安全

    Java 多线程基础(四)线程安全 在多线程环境下,如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线 ...

随机推荐

  1. 转 vue过滤器使用

    简单介绍一下过滤器,顾名思义,过滤就是一个数据经过了这个过滤之后出来另一样东西,可以是从中取得你想要的,或者给那个数据添加点什么装饰,那么过滤器则是过滤的工具.例如,从['abc','abd','ad ...

  2. 0506static【重点】

    static[重点] [重点] 1.[没有对象] [没有对象] [没有对象] 2.static 修饰的是一个资源共享类型的变量 3.静态成员变量的基本使用规范 static修饰的成员变量只能通过静态方 ...

  3. Java——参数传递

    写这篇文章时,其实还是不理解Java中的参数传递只有传值没有传址(传引用).这里引用知乎上大神的讲解来记录一下. 一.基本类型和引用类型 int num = 10; String str = &quo ...

  4. 五、Java - 集合

    一.集合 Java 中的集合类存放于 java.util 包中,是一个存放对象的容器. 集合存放的是对对象的引用,对象本身还是存在于 JVM 堆内存中. 存放的是对象,即引用数据类型,对于基本数据类型 ...

  5. sku算法详解及Demo~接上篇

    前言 做过电商项目前端售卖的应该都遇见过不同规格产品库存的计算问题,业界名词叫做sku(stock Keeping Unit),库存量单元对应我们售卖的具体规格,比如一部手机具体型号规格,其中ipho ...

  6. 万字超强图文讲解AQS以及ReentrantLock应用(建议收藏)

    | 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...

  7. java方法句柄-----4.你所不知道的MethodHandle【翻译】

    Method Handles in Java 1.介绍 在本文中,我们将探讨一个重要的API,它是在Java 7中引入的,并在Java 7版本之后更加完善:全限定名是:Java.lang.invoke ...

  8. vim的常见操作

    vim常见操作 复制 yank, y yy:复制整行 nyy/yny y^/y0:复制当前行到行头的内容 y$:复制当前到行尾的内容 yw:复制一个word nyw/ynw 复制n个word yG:复 ...

  9. 初学者对Git的使用安装教程,以及对unknown key type -rsa的解决办法

    第一次使用Git,诚惶诚恐. Git在每个电脑上第一次使用必须要配置环境,才能通过SSH秘钥的方式安全稳定的拉取代码! 此文适合对Git一无所知的小白观看,大神勿扰.下面我将讲解一个傻瓜式的Git安装 ...

  10. Java实现 蓝桥杯 算法训练 矩阵乘法

    算法训练 矩阵乘法 时间限制:1.0s 内存限制:512.0MB 提交此题 问题描述 输入两个矩阵,分别是ms,sn大小.输出两个矩阵相乘的结果. 输入格式 第一行,空格隔开的三个正整数m,s,n(均 ...