美文网首页
java多线程之wait()和sleep()的区别

java多线程之wait()和sleep()的区别

作者: 一个菜鸟JAVA | 来源:发表于2018-06-27 17:35 被阅读62次
    1.方法所属不同

    wait()是Object上的方法,而sleep()是属于Thread上的方法

    2.锁对象释放与否

    sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程,但是他的监控状态依然保持者,
    当指定的时间到了又会自动恢复运行状态。
    重点:不会释放锁对象
    wait()线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()或者notifyAll()
    方法后本线程才进入对象锁定池准备.
    重点:会释放锁对象
    下面给出测试代码:

    package com.zc.thread;
    
    /**
     * Created by zengchao 
     */
    public class App {
        public static void main(String[] args) throws InterruptedException {
            Object lock = new Object();
            //sleep()
            new Thread(new A(lock)).start();
            Thread.sleep(1000L);
            new Thread(new B(lock)).start();
            //wait()
    //        new Thread(new C(lock)).start();
    //        Thread.sleep(1000L);
    //        new Thread(new D(lock)).start();
        }
    
        private static class A extends Thread{
            private Object lock;
    
            public A(Object lock) {
                this.lock = lock;
            }
    
            @Override
            public void run() {
                synchronized (lock){
                    System.out.println("线程A获取到锁,进入5秒睡眠");
                    try {
                        Thread.sleep(5000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程A执行完成");
                }
            }
        }
    
        private static class B extends Thread{
            private Object lock;
            public B(Object lock) {
                this.lock = lock;
            }
            @Override
            public void run() {
                synchronized (lock){
                    System.out.println("线程B获取到锁");
                    System.out.println("线程B完成");
                }
            }
        }
    
        private static class C extends Thread{
            private Object lock;
    
            public C(Object lock) {
                this.lock = lock;
            }
    
            @Override
            public void run() {
                synchronized (lock){
                    System.out.println("线程C获取到锁");
                    System.out.println("线程C调用wait,释放锁");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程C执行完成");
                }
            }
        }
    
        private static class D extends Thread{
            private Object lock;
    
            public D(Object lock) {
                this.lock = lock;
            }
    
            @Override
            public void run() {
                synchronized (lock){
                    System.out.println("线程D获取到锁");
                    System.out.println("线程D执行完成,调用notify()唤醒线程C");
                    lock.notify();
                }
            }
        }
    }
    

    第一次执行

            Object lock = new Object();
            //sleep()
            new Thread(new A(lock)).start();
            Thread.sleep(1000L);
            new Thread(new B(lock)).start();
    

    结果:

    线程A获取到锁,进入5秒睡眠
    线程A执行完成
    线程B获取到锁
    线程B完成
    

    当线程A获取到锁后,进入5秒睡眠,但是线程A任然没有释放锁,所以线程B只能等待锁,而无法运行.而当线程A执行完成之后,
    释放了锁,所以B就可以执行了.

    第二次执行

            Object lock = new Object();
            //wait()
            new Thread(new C(lock)).start();
            Thread.sleep(1000L);
            new Thread(new D(lock)).start();
    

    结果:

    线程C获取到锁
    线程C调用wait,释放锁
    线程D获取到锁
    线程D执行完成,调用notify()唤醒线程C
    线程C执行完成
    

    首先线程C获取到了锁,然后调用wait()方法,C线程释放锁,D线程获取到锁,执行完成之后,调用notify()唤醒C线程,C线程继续执行.
    如果D线程不调用notify(),那么线程C则一直处于wait中,结果线程C执行完成不会打印出结果,程序也不会终止.

    总结

    上述是个人整理出来的,不正确的地方还请各位指正.第一点其实无关紧要,最重要记住第二点即可.

    相关文章

      网友评论

          本文标题:java多线程之wait()和sleep()的区别

          本文链接:https://www.haomeiwen.com/subject/vkriyftx.html