Java详细分析sleep和wait方法有哪些区别

目录
  • 一、sleep和wait方法的区别
  • 二、wait方法
    • wait方法的使用
    • wait结束等待的条件
  • 三、notify和notifyAll方法

一、sleep和wait方法的区别

  • 根本区别:sleep是Thread类中的方法,不会马上进入运行状态,wait是Object类中的方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程
  • 释放同步锁:sleep会释放cpu,但是sleep不会释放同步锁的资源,wait会释放同步锁资源
  • 使用范围: sleep可以在任何地方使用,但wait只能在synchronized的同步方法或是代码块中使用
  • 异常处理: sleep需要捕获异常,而wait不需要捕获异常

二、wait方法

  • 使当前执行代码的线程进行等待. (把线程放到等待队列中)
  • 释放当前的锁
  • 满足一定条件时被唤醒, 重新尝试获取这个锁.
  • wait 要搭配 synchronized 来使用,脱离 synchronized 使用 wait 会直接抛出异常.

wait方法的使用

wait方法

/**
 * wait的使用
 */
public class WaitDemo1 {
    public static void main(String[] args) {
        Object lock = new Object();
        Thread t1 = new Thread(() -> {
            System.out.println("线程1开始执行");
            try {
                synchronized (lock) {
                    System.out.println("线程1调用wait方法....");
                    // 无限期的等待状态
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1执行完成");
        }, "线程1");
        t1.start();
    }
}

有参wait线程和无参wait线程

/**
 * 有参wait线程和无参wait线程
 */
public class WaitDemo2 {
    public static void main(String[] args) {
        Object lock1 = new Object();
        Object lock2 = new Object();
        Thread t1 = new Thread(()->{
            System.out.println("线程1开始执行");
            synchronized (lock1){
                try {
                    lock1.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程1执行完成");
            }
        },"无参wait线程");
        t1.start();
        Thread t2 = new Thread(()->{
            System.out.println("线程2开始执行");
            synchronized (lock2){
                try {
                    lock2.wait(60*60*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程2执行完成");
            }
        },"有参wait线程");
        t2.start();
    }
}

wait结束等待的条件

①其他线程调用该对象的 notify 方法.

②wait 等待时间超时 (wait 方法提供一个带有 timeout 参数的版本, 来指定等待时间).

③其他线程调用该等待线程的 interrupted 方法, 导致 wait 抛出 InterruptedException 异常

三、notify和notifyAll方法

notify 方法只是唤醒某一个等待的线程

  1. 方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁的其它线程
  2. 如果有多个线程等待,随机挑选一个wait状态的线程
  3. 在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块之后才会释放对象锁

notify方法的使用

/**
 * wait的使用, 如果有多个线程等待,随机挑选一个wait状态的线程
 */
public class WaitNotifyDemo {
    public static void main(String[] args) {
        Object lock1 = new Object();
        Object lock2 = new Object();
        Thread t1 = new Thread(()->{
            System.out.println("线程1开始执行");
            try {
                synchronized (lock1) {
                    System.out.println("线程1调用wait方法");
                    lock1.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1执行完成");
        },"线程1");
        Thread t2 = new Thread(()->{
            System.out.println("线程2开始执行");
            try {
                synchronized (lock1) {
                    System.out.println("线程2调用wait方法");
                    lock1.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程2执行完成");
        },"线程2");
        t1.start();
        t2.start();
        // 唤醒 lock1 对象上休眠的线程的(随机唤醒一个)
        Thread t3 = new Thread(()->{
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程3开始执行");
            synchronized (lock1){
                //发出唤醒通知
                System.out.println("执行了唤醒");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"线程3");
        t3.start();
    }
}

notifyAll方法可以一次唤醒所有的等待线程

notifyAll方法的使用

/**
 * notifyAll-唤醒所有线程
 */
public class WaitNotifyAll {
    public static void main(String[] args) {
        Object lock = new Object();

        new Thread(() -> {
            System.out.println("线程1:开始执行");
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程1:执行完成");
            }
        }, "无参wait线程").start();

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程2:开始执行 |" + LocalDateTime.now());
                try {
                    lock.wait(60 * 60 * 60 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程2:执行完成 | " + LocalDateTime.now());
            }
        }, "有参wait线程").start();

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock) {
                System.out.println("唤醒所有线程");
                lock.notifyAll();
            }
        }).start();
    }
}

notify和notifyAll方法的区别

  1. 当你调用notify时,只有一个等待线程会被唤醒而且它不能保证哪个线程会被唤醒,这取决于线程调度器。
  2. 调用notifyAll方法,那么等待该锁的所有线程都会被唤醒,但是在执行剩余的代码之前,所有被唤醒的线程都将争夺锁定,这就是为什么在循环上调用wait,因为如果多个线程被唤醒,那么线程是将获得锁定将首先执行,它可能会重置等待条件,这将迫使后续线程等待。
  3. 因此,notify和notifyAll之间的关键区别在于notify()只会唤醒一个线程,而notifyAll方法将唤醒所有线程。

到此这篇关于Java详细分析sleep和wait方法有哪些区别的文章就介绍到这了,更多相关Java sleep与wait内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解Java中wait和sleep的区别

    1.概述 在这篇简短的文章中,我们将看一下核心Java 中的标准sleep()和wait()方法,并了解它们之间的差异和相似之处. 2. wait和sleep之间的一般差异 简单地说,wait()是一个用于线程同步的实例方法. 它可以在任何对象上调用,因为它在java.lang.Object上定义,但它只能从synchronized块中调用.它释放对象的锁定,以便另一个线程可以跳入并获取锁. 另一方面,Thread.sleep()是一个可以从任何上下文调用的静态方法.Thread.sleep()

  • Java中wait与sleep的区别讲解(wait有参及无参区别)

    目录 1. wait() 与wait( long timeout ) 区别 2. wait(0) 与 sleep(0)区别 3. wait 和sleep 释放代码 4. wait 与 sleep 区别 相同点: 不同点: 1. wait() 与wait( long timeout ) 区别 public class WaitDemo4 { public static void main(String[] args) { Object lock = new Object(); Object loc

  • java sleep()和wait()的区别点总结

    1.区别说明 wait()是Object的方法,sleep()是Thread的方法. wait()必须采用同步方法,不需要sleep()方法. 线程在同步方法中执行sleep()方法,不释放monitor锁,wait()方法释放monitor锁. 短暂休眠后,sleep()方法会主动退出阻塞,而wait()方法需要在没有指定wait时间的情况下被其他线程中断才能退出阻塞. 2.实例 import java.text.SimpleDateFormat; import java.util.Date;

  • JAVA线程sleep()和wait()详解及实例

    JAVA线程sleep()和wait()详解及实例 sleep 1.sleep是Thread的一个静态(static)方法.使得Runnable实现的线程也可以使用sleep方法.而且避免了线程之前相互调用sleep()方法,引发死锁. 2.sleep()执行时需要赋予一个沉睡时间.在沉睡期间(阻塞线程期间),CPU会放弃这个线程,执行其他任务.当沉睡时间到了之后,该线程会自动苏醒,不过此时线程不会立刻被执行,而是要等CPU分配资源,和其他线程进行竞争. 3.此外如果这个线程之前获取了一个机锁,

  • Java中sleep()与wait()的区别总结

    前言 对于sleep()方法,我们首先要知道该方法是属于Thread类中的.而wait()方法,则是属于Object类中的. sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态. 在调用sleep()方法的过程中,线程不会释放对象锁. 而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备 获取对象锁进入运行状态. 什么意思

  • java面试突击之sleep和wait有什么区别详析

    目录 前言 区别一:语法使用不同 区别二:所属类不同 区别三:唤醒方式不同 区别四:释放锁资源不同 sleep不释放锁 wait释放锁 区别五:线程进入状态不同 总结 前言 sleep 方法和 wait 方法都是用来将线程进入休眠状态的,并且 sleep 和 wait 方法都可以响应 interrupt 中断,也就是线程在休眠的过程中,如果收到中断信号,都可以进行响应,并抛出 InterruptedException 异常.那 sleep 和 wait 的区别都有哪些呢?接下来,我们一起来看.

  • Java线程中sleep和wait的区别详细介绍

    Java中的多线程是一种抢占式的机制,而不是分时机制.抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行. 共同点: 1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回. 2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException. 如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法.如果此刻线程B正在wait/sleep/

  • 详解Java中的sleep()和wait()的区别

    详解Java中的sleep()和wait()的区别 对于sleep()方法,我们首先要知道该方法是属于Thread类中的.而wait()方法,则是属于Object类中的. sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态. 在调用sleep()方法的过程中,线程不会释放对象锁. 而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象

  • Java详细分析sleep和wait方法有哪些区别

    目录 一.sleep和wait方法的区别 二.wait方法 wait方法的使用 wait结束等待的条件 三.notify和notifyAll方法 一.sleep和wait方法的区别 根本区别:sleep是Thread类中的方法,不会马上进入运行状态,wait是Object类中的方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程 释放同步锁:sleep会释放cpu,但是sleep不会释放同步锁的资源,wait会释放同步锁资源 使用范围: slee

  • Java详细分析String类与StringBuffer和StringBuilder的使用方法

    目录 String类基本概念 String字符串的存储原理 String类的常用构造方法 String类中常用方法 StringBuffer类 StringBuilder类 String类基本概念 String类属于引用数据类型,不属于基本数据类型. 在Java中只要是" "(双引号)中的,都是String对象. java中规定,双引号中的字符串是不可变的,也就是说"abc"自出生到死亡都不可能变成"abcd",也不能变成"ab&quo

  • Java详细分析Lambda表达式与Stream流的使用方法

    目录 Lambda Stream流 Lambda Lambda 表达式是一个匿名函数,我们可以把 lambda 表达式理解为一段可以传递的代码(将代码段像数据一样传递).使用它可以写出更简洁, 更灵活的代码.作为一种更紧凑的代码风格,使 java 语言的表达式能力得到的提升. 我们可以知道, Lambda表达式是为简化语法而存在的 ArrayList<String> list = new ArrayList<>(); list.add("a"); list.ad

  • Java详细分析讲解自动装箱自动拆箱与Integer缓存的使用

    目录 1. 前言 2. 包装类 3. 自动装箱与自动拆箱 4. Interger缓存 5. 回答题目 1. 前言 自动装箱和自动拆箱是什么?Integer缓存是什么?它们之间有什么关系? 先来看一道题目. Integer a = new Integer(1); Integer b = new Integer(1); System.out.println(a==b); Integer c = 1; Integer d = 1; System.out.println(c==d); Integer e

  • Java详细分析讲解泛型

    目录 1.泛型概念 2.泛型的使用 2.1泛型类语法 2.2泛型方法语法 2.3泛型接口语法 2.4泛型在main方法中的使用 3.擦除机制 4.泛型的上界 5.通配符 5.1通配符的上界 5.2通配符的下界 6.包装类 6.1装箱和拆箱 1.泛型概念 泛型就是将类型参数化 所谓类型参数化就是将类型定义成参数的形式,然后在使用此类型的时候的时候再传入具体的类型 到这我们可以看出来:泛型在定义的时候是不知道具体类型的,需要在使用的时候传入具体的类型,泛型可以用在类.接口和方法中,这样做的好处是一个

  • Java详细分析梳理垃圾回收机制

    目录 Java语言的垃圾回收 1.垃圾回收机制的基本概念 2.Java垃圾回收机制的好处 3.Java垃圾回收机制的特点 总结 Java语言的垃圾回收 1.垃圾回收机制的基本概念 问:1.什么是Java垃圾回收? 答:在Java语言的生命周期中,Java运行环境提供了一个系统的垃圾回收器线程,负责自动回收那些没有引用与之相连的对象所占用的内存.这种清楚无用对象进行内存回收的过程叫做垃圾回收. 问:2.Java垃圾回收的作用是什么? 答:垃圾回收是Java语言提供的一种自动内存回收的功能,可以让程

  • Java详细分析连接数据库的流程

    目录 注册驱动程序 创建连接 创建 SQL 语句 执行 SQL 语句 关闭连接 以下 5 个步骤是使用 JDBC 将 Java 应用程序与数据库连接所涉及的基本步骤. 注册驱动程序 创建连接 创建 SQL 语句 执行 SQL 语句 关闭连接 注册驱动程序 它首先是创建 JDBC 连接的重要部分.JDBC API 提供了一种Class.forName()用于显式加载驱动程序类的方法.例如,如果我们要加载 jdbc-odbc 驱动程序,那么我们将其称为如下. 使用 JDBC-ODBC 驱动程序注册的

  • Java详细分析讲解HashMap

    目录 1.HashMap数据结构 2.HashMap特点 3.HashMap中put方法流程 java集合容器类分为Collection和Map两大类,Collection类的子接口有Set.List.Queue,Map类子接口有SortedMap.如ArrayList.HashMap的继承实现关系分别如下 1.HashMap数据结构 在jdk1.8中,底层数据结构是“数组+链表+红黑树”.HashMap其实底层实现还是数组,只是数组的每一项都是一条链,如下 当链表过长时,会严重影响HashMa

  • Java详细分析LCN框架分布式事务

    目录 2PC两阶段提交协议 LCN LCN基本实现原理 搭建全局协调者 使用LCN解决分布式事务问题 源码分析 2PC两阶段提交协议 分布式事务通常采用2PC协议,全称Two Phase Commitment Protocol.该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题.分布式事务通过2PC协议将提交分成两个阶段: 阶段一为准备(prepare)阶段.即所有的参与者准备执行事务并锁住需要的资源.参与者ready时,向transaction manager报告已准备就绪.

  • Java 详细分析四个经典链表面试题

    前言: 上一章更到了链表,虽然知道了什么是链表,链表的结构是怎么样的,但这是远远不够的,我们只清楚了点皮毛,如果让你做题你还是会无从下手,所以我们必须多做题,在做题的过程中慢慢的我们就会觉得一切都很简单.下面我们就来做几道经典的链表面试题!!!!!! 第一题 题目:反转一个单链表 每个节点是不变的,只是修改当前每个节点的指向 看图分析: 问题分析: 每个节点是不变的,只需要修改当前每个节点的指向,第一个节点指向变成null,第二个节点的指向是第一个节点. 问题讲解: 我们需要定义四个节点变量 h

随机推荐