高并发编程-深入分析wait和sleep的区别并结合源码示例佐证

简介: 高并发编程-深入分析wait和sleep的区别并结合源码示例佐证

20191031000606569.png


概述


wait和sleep的区别,这个确实是面试中非常常见的一道题目,这里我们通过源码并结合示例来一起加深下对wait和sleep的理解 。

主要有4点不同


  • sleep是Thread的方法,wait是Object的方法
  • sleep不会释放锁(Monitor), wait会让当前线程释放锁
  • sleep 不依赖 Monitor,但是wait需要依赖Monitor
  • sleep方法不需要被唤醒,wait需要唤醒 (wait(long millons) 方法除外

接下来我们分别来看下这4点区别


区别

sleep是Thread的方法,wait是Object的方法

直接看下源码即可

Object#wait





20191009225109926.png


Thread#sleep

20191009225138995.png


sleep不会释放锁(Monitor), wait会让当前线程释放锁

sleep不会释放锁(Monitor) 举个例子

package com.artisan.test;
import java.util.Date;
import java.util.stream.Stream;
public class SleepAndWaitDiffDemo {
    private final static Object LOCK = new Object();
    private static void method1() {
        synchronized (LOCK){
            System.out.println(Thread.currentThread().getName() + " -- " + new Date());
            try {
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
       // 开启两个线程
        Stream.of("T1","T2").forEach(threadName -> {
            new Thread(threadName){
                @Override
                public void run() {
                    super.run();
                    // 调用methood1
                    method1();
                }
            }.start();
        });
    }
}


输出


20191009233633723.png

wait会让当前线程释放锁

package com.artisan.test;
import java.util.Date;
import java.util.stream.Stream;
public class SleepAndWaitDiffDemo {
    private final static Object LOCK = new Object();
    private static void method2() {
        synchronized (LOCK){
            System.out.println(Thread.currentThread().getName() + " -- " + new Date());
            try {
                LOCK.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
       // 开启两个线程
        Stream.of("T1","T2").forEach(threadName -> {
            new Thread(threadName){
                @Override
                public void run() {
                    super.run();
                    // 调用methood2
                    method2();
                }
            }.start();
        });
    }
}


20191009234033178.png


sleep 不依赖 Monitor,但是wait需要依赖Monitor

package com.artisan.test;
public class SleepAndWaitDiffDemo {
    private final static Object LOCK = new Object();
    private static void method1() {
        try {
            Thread.sleep(2_000);
            System.out.println("method1休眠2秒结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private static void method2() {
        try {
          // 不加synchronized关键字,会抛出IllegalMonitorStateExceptio
            LOCK.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        method1();
        method2();
    }
}


运行结果


20191009232734397.png


如何改呢?

private static void method2() {
        synchronized (LOCK){
            try {
                LOCK.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


synchronized (LOCK),然后 LOCK.wait即可 。


sleep方法不需要被唤醒,wait需要唤醒 (wait(long millons) 方法除外)


sleep不会释放锁(Monitor), wait会让当前线程释放锁 这个例子中,我们可以看到sleep方法执行后,整个主线程就退出了,但 wait方法的,T1 和 T2 都处于waiting状态了,需要被唤醒才能继续执行…

相关文章
|
1月前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
55 3
|
1月前
|
并行计算 算法 搜索推荐
探索Go语言的高并发编程与性能优化
【10月更文挑战第10天】探索Go语言的高并发编程与性能优化
|
2月前
|
网络协议 Java Linux
高并发编程必备知识IO多路复用技术select,poll讲解
高并发编程必备知识IO多路复用技术select,poll讲解
|
1月前
|
Java Linux 应用服务中间件
【编程进阶知识】高并发场景下Bio与Nio的比较及原理示意图
本文介绍了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO采用传统的线程模型,每个连接请求都会创建一个新线程进行处理,导致在高并发场景下存在严重的性能瓶颈,如阻塞等待和线程创建开销大等问题。而NIO则通过事件驱动机制,利用事件注册、事件轮询器和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,显著提升了系统的并发处理能力。
58 0
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的高并发慕课网的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的高并发慕课网的详细设计和实现(源码+lw+部署文档+讲解等)
|
6月前
|
存储 关系型数据库 MySQL
《MySQL 入门教程》第 05 篇 账户和权限,Java高并发编程详解深入理解pdf
《MySQL 入门教程》第 05 篇 账户和权限,Java高并发编程详解深入理解pdf
|
6月前
|
JavaScript Java 测试技术
基于Java的高并发慕课网的设计与实现(源码+lw+部署文档+讲解等)
基于Java的高并发慕课网的设计与实现(源码+lw+部署文档+讲解等)
63 2
|
6月前
|
Java
高并发编程之JUC 三大辅助类和读写锁
高并发编程之JUC 三大辅助类和读写锁
51 1
|
5月前
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
489 0
|
3月前
|
监控 算法 Java
企业应用面临高并发等挑战,优化Java后台系统性能至关重要
随着互联网技术的发展,企业应用面临高并发等挑战,优化Java后台系统性能至关重要。本文提供三大技巧:1)优化JVM,如选用合适版本(如OpenJDK 11)、调整参数(如使用G1垃圾收集器)及监控性能;2)优化代码与算法,减少对象创建、合理使用集合及采用高效算法(如快速排序);3)数据库优化,包括索引、查询及分页策略改进,全面提升系统效能。
48 0