目录
一、sleep和wait方法的区别
二、wait方法
wait方法的使用
wait结束等待的条件
三、notify和notifyAll方法
首页 Java java教程 Java中sleep和wait方法有什么区别

Java中sleep和wait方法有什么区别

May 06, 2023 am 09:52 AM
java sleep wait

    一、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方法有什么区别的详细内容。更多信息请关注PHP中文网其他相关文章!

    本站声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热门文章

    R.E.P.O.能量晶体解释及其做什么(黄色晶体)
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳图形设置
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您听不到任何人,如何修复音频
    4 周前 By 尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25:如何解锁Myrise中的所有内容
    1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

    热工具

    记事本++7.3.1

    记事本++7.3.1

    好用且免费的代码编辑器

    SublimeText3汉化版

    SublimeText3汉化版

    中文版,非常好用

    禅工作室 13.0.1

    禅工作室 13.0.1

    功能强大的PHP集成开发环境

    Dreamweaver CS6

    Dreamweaver CS6

    视觉化网页开发工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神级代码编辑软件(SublimeText3)

    Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

    Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

    Java 中的随机数生成器 Java 中的随机数生成器 Aug 30, 2024 pm 04:27 PM

    Java 随机数生成器指南。在这里,我们通过示例讨论 Java 中的函数,并通过示例讨论两个不同的生成器。

    Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

    Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

    Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

    Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

    Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

    在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

    突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

    Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

    Java 中的时间戳至今 Java 中的时间戳至今 Aug 30, 2024 pm 04:28 PM

    Java 中的时间戳到日期指南。这里我们还结合示例讨论了介绍以及如何在java中将时间戳转换为日期。

    创造未来:面向零基础的 Java 编程 创造未来:面向零基础的 Java 编程 Oct 13, 2024 pm 01:32 PM

    Java是热门编程语言,适合初学者和经验丰富的开发者学习。本教程从基础概念出发,逐步深入讲解高级主题。安装Java开发工具包后,可通过创建简单的“Hello,World!”程序实践编程。理解代码后,使用命令提示符编译并运行程序,控制台上将输出“Hello,World!”。学习Java开启了编程之旅,随着掌握程度加深,可创建更复杂的应用程序。

    See all articles