sleep和wait的区别是一个老生常谈的问题。Sleep 是 Thread类的方法, wait是Object类的方法。但是关键的区别是对锁的操作问题。

当我们调用sleep的时候,线程进入休眠,但是获得的锁并不释放

而是用wait的时候,线程进入等待队列,会释放获得的锁

看一段代码:

public class TestWait {
 
    public static void main(String[] args) throws InterruptedException {
        Data d = new Data();
        WaitTest st1 = new WaitTest(d);
        WaitTest2 st2 = new WaitTest2(d);
 
        st1.start();
        Thread.sleep(1000);
        st2.start();
    }
 
    static class WaitTest extends Thread {
 
        Data d;
 
        public WaitTest(Data d) {
            super("thread1");
            this.d = d;
        }
 
        @Override
        public void run() {
            try {
                System.out.println("wait1Test ..." + d.getData());
            } catch (InterruptedException ex) {
            }
        }
    }
 
    static class Data {
 
        private String sd = "data";
 
        private synchronized String getData() throws InterruptedException {
            while (Thread.currentThread().getName().equals("thread1")) {
                wait();
            }
            return sd;
        }
    }
 
    static class WaitTest2 extends Thread {
 
        private Lock s;
        Data d;
 
        public WaitTest2(Data d) {
            this.d = d;
        }
 
        @Override
        public void run() {
            try {
                System.out.println("waitTest2 ..." + d.getData());
            } catch (InterruptedException ex) {
            }
        }
    }
}

线程一和线程二共享Data。但是当读取Data时,如果是线程一则无限wait。看下程序的输出:

waitTest2 ...data

程序会输出线程二的打印。这说明线程一在进入wait时,释放了锁,其他线程可以继续进入getData方法。

下面我们修改Data类,将wait换成sleep之后

    static class Data {
 
        private String sd = "data";
 
        private synchronized String getData() throws InterruptedException {
            while (Thread.currentThread().getName().equals("thread1")) {
                Thread.sleep(1000);
            }
            return sd;
        }
    }

运行程序,发现程序一直在跑,但是并没有输出线程二的打印语句。这说明如果我们使用sleep,线程进入休眠时,线程二也不能进入,因为锁一直被线程一占住。

Sleep 和 Wait 关于锁释放的区别的更多相关文章

  1. java 哪些情况下会使对象锁释放

    Java_多线程_锁释放 问:Java多线程运行环境中,在哪些情况下会使对象锁释放?答:由于等待一个锁的线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不再需要锁的时候及时释放锁是很重要的 ...

  2. synchronized同步代码块锁释放

    今天发现自己写的线上程序出现数据库不能同步的问题,查看日志已经停止记录,随后使用jstack查看线程的运行状况,发现有个同步线程锁住了. 以下是jstack -l 637  问题线程的内容. &quo ...

  3. 对象的notify方法的含义和对象锁释放的三种情况

    1,notify的含义     (1)notify一次只随机通知一个线程进行唤醒 (2)在执行了notify方法之后,当前线程不会马上释放该对象锁,呈wait状态的线程也不能马上获得该对象锁, 要等到 ...

  4. XEvent--Demo--使用XEvent来捕获在数据库DB1上发生的锁请求和锁释放

    --==============================================================--使用XEvent来捕获在数据库DB1上发生的锁请求和锁释放--=== ...

  5. 并发编程 - 进程 - 1.互斥锁/2.模拟抢票/3.互斥锁与join区别

    1.互斥锁: 互斥锁:Lock 原理就是把并发变成串行,一个一个运行,不错乱,但效率低 保证多个进程修改一块数据时,大家是一个一个修改,不错乱 mutex.acquire() mutex.releas ...

  6. 深入浅出 Java Concurrency (9): 锁机制 part 4 锁释放与条件变量 (Lock.unlock And Condition)

    本小节介绍锁释放Lock.unlock(). Release/TryRelease unlock操作实际上就调用了AQS的release操作,释放持有的锁. public final boolean ...

  7. [Java并发] AQS抽象队列同步器源码解析--独占锁释放过程

    [Java并发] AQS抽象队列同步器源码解析--独占锁获取过程 上一篇已经讲解了AQS独占锁的获取过程,接下来就是对AQS独占锁的释放过程进行详细的分析说明,废话不多说,直接进入正文... 锁释放入 ...

  8. ReentrantLock 锁释放源码分析

    ReentrantLock 锁释放源码分析: 调用的是unlock 的方法: public void unlock() { sync.release(1); } 接下来分析release() 方法: ...

  9. ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放

    ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放 前言 加锁逻辑已经介绍完毕,那当一个线程重复加锁是如何处理的呢? 锁重入 在上一小节中,可以看到加锁的过程,再回头看 ...

随机推荐

  1. import与from...import...的区别

    from ... import ... 的用法和直接import的区别: 1.直接使用import时,如果需要使用到导入模块内的属性和方法,必须使用模块名.属性和模块名.方法的方式进行调用 2.使用f ...

  2. js 点击页面出现烟花 心形

    css :1 body{width:1000px; height:500px;} input{ margin:100px; width:250px; height: 50px } 3 .Firewor ...

  3. sharepoint_study_11

    描述:修改管理员密码和账户后,管理中心无法打开.(提示:HTTP Error 503. The service is unavailable.) 解决: 1.打开iis 2.右击“应用程序池”下的”S ...

  4. 江西财经大学第一届程序设计竞赛 H

    链接:https://www.nowcoder.com/acm/contest/115/H来源:牛客网 题目描述 晚上,小P喜欢在寝室里一个个静静的学习或者思考,享受自由自在的单身生活. 他总是能从所 ...

  5. NFS网络储存系统

    为什么用NFS网络文件存储系统? 1)实现数据信息统一一致 2)节省局域网数据同步传输的带宽 3)节省网站架构中服务器硬盘资源 NFS系统存储原理介绍 RPC服务类似一个中介服务,NFS服务端与NFS ...

  6. UDP通讯模型简单示例

    1. UDP通讯模型 2. 服务器端 ① 创建一个socket,用函数socket() ② 绑定IP地址.端口等信息到socket上,用函数bind() ③ 循环接收数据,用函数recvfrom() ...

  7. win7旗舰版+caffe+vs2013+matlab2014b(无GPU版)

    参考网站: http://www.cnblogs.com/njust-ycc/p/5776286.html 无法找到gpu/mxGPUArray.h: No such file or director ...

  8. HTTP.SYS远程代码执行漏洞测试(ms15-034)

    1.HTTP.SYS远程代码执行漏洞简介 首先漏洞编号:CVE-2015-1635(MS15-034 ) 远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未 ...

  9. PHP速学

    基本代码 <?php echo "Hello world";?> 变量定义 <?php $a=true; $bool_value=true; $integer_v ...

  10. python文件操作和集合(三)

    对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句柄操作文件 3.关闭文件. 文件基本操作:         f = open('file.txt','r') #以 ...