首页 > 编程语言 >并发编程[5]_wait和notify

并发编程[5]_wait和notify

时间:2024-08-23 10:48:15浏览次数:10  
标签:... obj log 25 编程 notify thread1 wait


1. wait 和 notify

wait() 方法是Object类中的方法,他的作用是让当前线程进入等待状态,而使用notify() 方法可以唤醒。

image

  • wait(long): void ,参数是毫秒,表示等待毫秒数,直到时间结束或被唤醒;
  • wait(long, int): void ,第一个参数是毫秒,第二个参数是纳秒,如果纳秒在0-999999之间,则第一个参数值+1, 最后调用wait(long) 方法;
  • wait(): void ,调用wait(0) ,表示无限等待。
  • notify(): void,随机唤醒一个正在等待中的线程
  • notifyAll():void ,唤醒所有正在等待中的线程

调用上述方法前,得保证当前线程是此对象的监视器所有者,即要获得对象的锁,否则直接调上述方法,会报出 java.lang.IllegalMonitorStateException 的错误。

简单的例子1:

public class Test1 {
    private static final Logger log = LoggerFactory.getLogger(Test1.class);
    // 自定义锁
    private final static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread("thread1") {
            @Override
            public void run() {
                try {
                    synchronized (obj){
                        log.debug("wait()");
                        obj.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.debug("唤醒后的操作");
            }
        };
        thread.start();

        Thread.sleep(1000);
        synchronized (obj){
            obj.notify();
            log.debug("唤醒");
        }
    }
}

运行结果:

2021-04-25 22:31:49.151  [thread1] - wait()
2021-04-25 22:31:50.152  [main] - 唤醒
2021-04-25 22:31:50.152  [thread1] - 唤醒后的操作

2. wait 和 sleep

wait 和 sleep 都是可以让线程进入休眠的状态,但是具体的又有很大的不同。

sleep wait
所属类 Thread 类中的静态方法 Object 类中的非静态方法
参数 有参 有参和无参
调用后的线程状态 TIMED_WAITING WAITING(无参时) 或 TIMED_WAITING
不会释放锁 会释放锁
使用场景 任何地方都能使用 需取得锁后,才能调用

例子:
根据运行结果的时间来判断会不会释放锁。
测试sleep不会释放锁:

public class Test1 {
    private static final Logger log = LoggerFactory.getLogger(Test1.class);
    // 自定义锁
    private final static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread("thread1") {
            @Override
            public void run() {
                try {
                    synchronized (obj){
                        log.debug("sleep(5000) 中...");
                        Thread.sleep(5000);
                    }
                    log.debug("休眠结束...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread1.start();
        Thread.sleep(1000);
        log.debug("线程1:{}",thread1.getState());
        synchronized (obj){
            log.debug("正在访问obj...");
        }
    }
}

运行结果:

2021-04-25 22:55:50.762  [thread1] - sleep(5000) 中...
2021-04-25 22:55:51.762  [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:55.764  [thread1] - 休眠结束...
2021-04-25 22:55:55.764  [main] - 正在访问obj...

测试wait会释放锁:

public class Test1 {
    private static final Logger log = LoggerFactory.getLogger(Test1.class);
    // 自定义锁
    private final static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread("thread1") {
            @Override
            public void run() {
                try {
                    synchronized (obj){
                        log.debug("wait(5000) 中...");
                        obj.wait(5000);
                    }
                    log.debug("休眠结束...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        thread1.start();
        Thread.sleep(1000);
        log.debug("线程1:{}",thread1.getState());
        synchronized (obj){
            log.debug("正在访问obj...");
        }
    }
}

运行结果

2021-04-25 22:55:07.307  [thread1] - wait(5000) 中...
2021-04-25 22:55:08.308  [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:08.308  [main] - 正在访问obj...
2021-04-25 22:55:12.308  [thread1] - 休眠结束...

标签:...,obj,log,25,编程,notify,thread1,wait
From: https://www.cnblogs.com/Aeons/p/18375542

相关文章

  • 并发编程[2]_线程的常用方法
    介绍一下线程常用的一些方法1.run()和start()start()方法让线程进入就绪状态run()方法是Runnable中的一个抽象方法,线程启动时就会调用run()方法(1)如果直接调用run()方法,是不会启动新线程的publicclassTest1{privatestaticfinalLoggerlog=LoggerF......
  • 并发编程[1]_线程的创建
    介绍线程创建的两种基本的方法:继承Thread类和实现Runnable接口1.继承Thread类自定义类继承Thread类,重写run()方法importorg.slf4j.LoggerFactory;/***@author:yt*@date:2021/4/1222:09*@description:创建Thread类继承Thread*/publicclassMyTh......
  • 并发编程[3]_java线程的六种状态
    java线程状态1.操作系统进程的五种状态网上找了一张图:2.java线程的六种状态Thread类中getState()方法可以获取线程的状态,返回值是Thread类中的enum类型,取值有NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED六种状态。java的线程状态将阻塞状态细分为BLOCKED,WAITING......
  • 大模型重塑软件架构·开启智能编程新纪元 |大模型书籍推荐
    在大模型时代洪流中,架构设计师就像时代舵手,不仅精通传统架构设计精髓,更要拥抱数据洪流与AI智能的浪潮。他们需具备前瞻视野,深入理解大模型技术如何重塑业务逻辑与系统架构,灵活运用云计算、微服务、自动化运维等现代技术栈,构建高可用、可扩展、智能化的系统架构。今天,小编......
  • 编程创建一个Cale计算类,在其中定义2个变量表示两个操作数,定义四个方法实现求和、差、
    1publicclassHomework06{2//编写一个main方法3publicstaticvoidmain(String[]args){45Calecale=newCale(2,10);6System.out.println("和="+cale.sum());7System.out.println("差="+cale.minus());......
  • 更懂你的文心快码 Inline Chat 全新上线,带来更加简化交互式的编程体验!
    更懂你的文心快码 InlineChat 全新上线,带来更加简化交互式的编程体验,充分适应程序员的编程和使用习惯。代码行内集成、智能生成、智能问答,无需跳出编辑区,AI就在你手边看,开发过程更流畅。那么Inlinechat如何助力实际开发场景?CoCo为大家展开讲讲。更懂你的文心快码......
  • bat编程
    .bat文件(批处理文件)是Windows系统中用于自动化执行一系列命令的脚本文件。下面是一些.bat文件的基本语法和常用命令:1.注释使用REM命令或@echooff后面的行(在@echooff生效的情况下)来添加注释。注释不会被执行,仅用于说明。REM这是一个注释@echooff::这也是一......
  • 干货-并发编程提高——线程池(十二)
    提到线程池就不得不说池化技术,那么什么是池化技术呢?池化技术能够减少资源对象的创建次数,提高程序的性能。特别是高并发下这种提高更加明显。使用池化技术缓存的资源有如下特点:对象的创建时间长对象创建需要大量资源对象创建后可被重复使用有没有点儿像共享单车?一个资......
  • Scratch编程环境的暗色模式:探索可访问性的边界
    标题:Scratch编程环境的暗色模式:探索可访问性的边界Scratch,这个广受欢迎的图形化编程平台,由麻省理工学院媒体实验室开发,一直致力于为用户提供友好且易于访问的编程体验。随着用户对编程环境个性化需求的增长,Scratch的编程环境是否支持暗模式或可访问性选项,成为了编程教育领......
  • Scratch的诞生:开启编程世界的大门
    标题:Scratch的诞生:开启编程世界的大门Scratch,这款全球数百万儿童和青少年的编程启蒙工具,自诞生之日起就以其独特的图形化编程界面和强大的社区支持,引领着编程教育的潮流。本文将详细探讨Scratch的起源,它如何从一个教育项目成长为全球性的编程学习平台,并提供一些基础的Scrat......