zoukankan      html  css  js  c++  java
  • java sleep()和wait()的区别

    java sleep()和wait()的区别?

    sleep()和wait()都能阻塞当前线程。

    区别1:

    sleep()属于Thread类;wait()属于Object类。

    区别2:

    调用sleep()方法的过程中,线程不会释放对象锁。

    调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

    打个比较有味道的比喻:sleep和wait两个小朋友在拉屎,然后老师说你们两个不要拉屎了,wait小朋友乖乖地听话提起裤子从厕所里面出来了;sleep小朋友也很听话,也先不拉屎了,但是呢就是不从厕所出来;老师对sleep小朋友也没办法,只好不管他了,然后一扭头看到wait小朋友脸憋得通红,只得让wait小朋友继续去厕所;此时厕所已经有人了,wait小朋友只好重新排队;sleep小朋友在厕所听到老师走了也就继续他的事业了。

    这里的两个小朋友就是线程,厕所就是对象锁。

    看个示例程序:

    public class MyTest {
    
        public static void main(String[] args) throws InterruptedException {
    
            Object o = new Object();
    
            Thread t1 = new Thread(() -> {
                synchronized (o) {
                    System.out.println("start t1");
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                    }
                    System.out.println("end t1");
                }
            });
    
    
            Thread t2 = new Thread(() -> {
                synchronized (o) {
                    System.out.println("start t2");
                    try {
                        o.notify();
                        Thread.sleep(100L);
                        System.out.println("t2 sleep 100 mills");
                    } catch (Exception e) {
                    }
    
                }
                System.out.println("t2 sleep 200 mills");
                try {
                    Thread.sleep(200L);
                } catch (InterruptedException e) {
                }
                System.out.println("end t2");
            });
    
            t1.start();
            Thread.sleep(10L);
            t2.start();
        }
    
    }

    执行结果如下:

    start t1
    start t2
    t2 sleep 100 mills
    end t1
    t2 sleep 200 mills
    end t2

    两个线程执行过程如下:

    1. 线程1先开始执行,获得对象锁o,输出一行字符后随即被wait方法阻塞,释放对象锁o;

    2. 线程2开始执行,获得线程1释放的对象锁o,输出一行字符后调用对象锁o的notify方法唤醒线程1;

    3. 线程2开始sleep,但此时线程2仍持有对象锁o,线程1虽已被唤醒但无法获得对象锁o只好继续阻塞;

    4. 线程2 sleep结束,输出一行字符,释放对象o,随即输出一行字符,然后继续sleep;

    5. 线程1得到对象锁,结束阻塞状态,继续执行直到结束;

    6. 线程2 sleep结束,继续执行直到结束。

    从这个过程中可以了解sleep和wait的区别与使用方法。

    再看一个基于wait方法实现的简单锁:

    public class MyLock {
        
        private boolean flag = false;
    
        public void lock() {
            synchronized (this) {
                while (flag) {
                    try {
                        wait();// 已经加锁,当前线程需要等待 
                    } catch (InterruptedException e) {
                    }
                }
                flag = true;
            }
        }
    
        public void unlock() {
            synchronized (this) {
                flag = false;
                notifyAll();// 释放锁时通知其他线程 
            }
        }
    }
  • 相关阅读:
    C#Excel上传批量导入sqlserver
    RadioButtonList 和CheckBoxList根据后天数据库的值加载时选中其选项
    vue增强第三方UI库(element-ui)
    Vue项目中简易演示axios解耦
    Vue 权限控制 使用自定义指令 代替v-if
    实现水平居中垂直居中的案例
    Sublime Text3高效开发之编写代码块(snippet)
    CSS:布局篇_用flex布局实现两边顶宽中间自适应(圣杯布局&双飞翼布局)
    CSS:盒子_每个元素都有两个盒子(《CSS世界》笔记-块级元素)
    CSS:布局篇_两边顶宽中间自适应(圣杯布局&双飞翼布局)
  • 原文地址:https://www.cnblogs.com/amunote/p/10223122.html
Copyright © 2011-2022 走看看