美文网首页
Wait和sleep的区别

Wait和sleep的区别

作者: leenpong | 来源:发表于2018-08-27 12:29 被阅读0次

wait方法是Object里面的一个native方法,而sleep是Thread里面的方法,下面分别来看两个方法的源码:

/**
     * Causes the current thread to wait until another thread invokes the
     * {@link java.lang.Object#notify()} method or the
     * {@link java.lang.Object#notifyAll()} method for this object.
     * In other words, this method behaves exactly as if it simply
     * performs the call {@code wait(0)}.
     * <p>
     * The current thread must own this object's monitor. The thread
     * releases ownership of this monitor and waits until another thread
     * notifies threads waiting on this object's monitor to wake up
     * either through a call to the {@code notify} method or the
     * {@code notifyAll} method. The thread then waits until it can
     * re-obtain ownership of the monitor and resumes execution.
     * This method should only be called by a thread that is the owner
     * of this object's monitor. See the {@code notify} method for a
     * description of the ways in which a thread can become the owner of
     * a monitor.
      *This method should only be called by a thread that is the owner
     * of this object's monitor. See the {@code notify} method for a
     * description of the ways in which a thread can become the owner of
     * a monitor.
     *
**/
public final native void wait() throws InterruptedException;

从官方的注释可以知道,当前线程对要持有当前对象的资源锁,并且当前线程会释放锁。
而且要调用notify唤醒wait的线程时,必须先持有对象的资源锁,从这里可以知道,不管是调用wait或者
notify,都要持有同一个对象的锁。

public void funcWait() {
    synchronized(obj) {
        obj.wait()
}
}

public void funcNotify() {
    synchronized(obj) {
        obj.notify()
}
}

Sleep

    /**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds, subject to
     * the precision and accuracy of system timers and schedulers. The thread
     * does not lose ownership of any monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static void sleep(long millis) throws InterruptedException {
        Thread.sleep(millis, 0);
    }

    @FastNative
    private static native void sleep(Object lock, long millis, int nanos)
        throws InterruptedException;

发现官方注释上面,sleep的时候是没有 释放资源锁的。这就是跟wait最大的区别.
下面写对应例子验证:

    private Object waitObj = new Object();
    public void funForWait(int id) {
        synchronized(waitObj) {
            Log.e("@@@", "wait  begin   " + id);
            try {
                waitObj.wait();
            }catch (Exception e) {
                e.printStackTrace();
            }
            Log.e("@@@", "wait  end : " + id);
        }
    }

    public void funForSleep(int id) {
        synchronized(waitObj) {
            Log.e("@@@", "sleep  begin : " + id);
            try {
                Thread.sleep(2000);
            }catch (Exception e) {
                e.printStackTrace();
            }
            Log.e("@@@", "sleep  end : " + id);
        }
    }

        for (int  i = 0; i < 4; i++) {
            final int id = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    funForWait(id);
                }
            }).start();
        }

上面测试wait和sleep分别输出入下:

wait   
E/@@@: wait  begin   0
E/@@@: wait  begin   1
E/@@@: wait  begin   2
E/@@@: wait  begin   3

sleep:
E/@@@: sleep  begin : 0
E/@@@: sleep  end : 0
E/@@@: sleep  begin : 1
E/@@@: sleep  end : 1
E/@@@: sleep  begin : 3
E/@@@: sleep  end : 3
E/@@@: sleep  begin : 2
E/@@@: sleep  end : 2

从上面的输出可以看出,当调用wait的时候,其他线程是可以继续调用funForwait方法并且访问

Log.e("@@@", "wait begin " + id);

而调用sleep的则不行,从这里可以看出,wait的时候,线程是释放了对Object的锁,而sleep却没有,所以

Log.e("@@@", "sleep begin : " + id);

这段代码当第一个线程进入sleep的时候,其他线程被挂起并且访问不了这段代码,原因是因为当前线程还是持有Object资源锁。

如果想要中断当前正在挂起等待的线程,可以调用

/**
  * <p> If this thread is blocked in an invocation of the {@link
     * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
     * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
     * class, or of the {@link #join()}, {@link #join(long)}, {@link
     * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
     * methods of this class, then its interrupt status will be cleared and it
     * will receive an {@link InterruptedException}.
***
   */
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                nativeInterrupt();
                b.interrupt(this);
                return;
            }
        }
        nativeInterrupt();
    }

相关文章

  • Java中wait和sleep方法有什么区别?

    参考Java中wait和sleep方法的区别java中的 sleep() 和 wait() 有什么区别? wait...

  • sleep和wait区别以及while死循环

    sleep()和wait()区别 sleep()和wait()的区别属于老生常谈了,大部分Java面试或者笔试都会...

  • sleep() wait() 区别

    sleep() wait() 区别 wait()和sleep()最大的不同在于:wait()会释放对象锁,而sle...

  • 线程——wait和sleep

    wait()和sleep()的区别 sleep(): 1、sleep()是Thread类的方法; 2、sleep(...

  • 面试相关之 Java 并发

    1. sleep()和wait()的区别?参考回答:sleep()来自Thread类;wait()来自Object...

  • 线程考点

    1、sleep和wait的区别 sleep是Thread类的方法、wait是Object类中定义的方法sleep方...

  • Java多线程

    Java中的sleep()和wait()的区别 sleep属于Thread类的静态方法。而wait()方法,则是属...

  • 【进阶】 wait sleep

    wait sleep 区别 不同: wait会释放锁,而sleep不会释放锁 wait只能在同步方法和同步代码块中...

  • java sleep和wait相关知识汇总

    java sleep和wait的区别? sleep是Thread类的方法,wait是Object类中的方法,尽管这...

  • 解答

    Java sleep 和wait区别sleep 休眠让出CUP,不改变锁的状态wait 让出CUP,也将锁让出

网友评论

      本文标题:Wait和sleep的区别

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