多线程基础之sleep()、wait()、await()的区别

2,556 阅读1分钟

1、来源不同

  • wait()方法来自Object类
public class Object {

    private static native void registerNatives();
    static {
        registerNatives();
    }

    public final void wait() throws InterruptedException {
        wait(0);
    }
    
    public final native void wait(long timeout) throws InterruptedException;
}

  • sleep来自Thread类
public
class Thread implements Runnable {
    /* Make sure registerNatives is the first thing <clinit> does. */
    private static native void registerNatives();
    static {
        registerNatives();
    }
    
    public static native void sleep(long millis) throws InterruptedException;
    
    public static void sleep(long millis, int nanos) throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        sleep(millis);
    }

2、关于锁得释放

  • sleep()方法并不释放锁,只是会让出cpu
  • wait()方法会释放掉锁,让出系统资源;需要调用notify、notifyAll对其进行唤醒

3、异常捕获问题

  • sleep 需要捕获异常
  • wait、notify、notifyAll 不需要捕获异常

4、使用范围

wait,notify和 notifyAll只能在同步控制方法或者同步控制块里面使用,而 sleep 可以在任何地方使用(使用范围)

5、与synchronized 一起使用

  • 1)用 obj 的 wait 和 notify 函数前必须获取对象锁,即在 synchronized(obj){...}代码块中。

  • 2)如果都在 synchronized 代码块中,wait(obj)函数可以释放锁,而 sleep 函数则不释放锁。

6、wait和await

wai()是Object类提供的,一般与synchronized联合使用。调用wait之后会释放锁,导致线程等待。唤醒进程使用notify()或者notifyAll();await()是Condition类当中的,一般与Lock联合使用。

wait用法
synchronized(obj){
 obj.wait();//消费方没东西了,等待
}

synchronize(obj){ 
    obj.notify();//有东西了,唤醒 消费进程
}

Lock则是由Lock控制锁,Condition来控制被阻塞线程

await用法
// 消费者
lock.lock();
condition.await();
lock.unlock();


//生产者
lock.lock(); 
condition.signal(); 
lock.unlock();

参考文章