Wait和sleep的区别

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)}.
     * 

* 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
     *          interrupted status 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资源锁。

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

/**
  * 

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(); }

你可能感兴趣的:(Wait和sleep的区别)