Java中的await与wait的区别
在Java中,await和wait都是用于线程间通信的方法,但它们之间存在一些关键的区别,下面我们将详细介绍这两种方法的区别。
1、来源不同
await是java.util.concurrent.locks.LockSupport类中的一个方法,而wait则是Object类的一个成员方法,这意味着await只能在实现了LockSupport接口的类中使用,而wait则可以在任何Java对象上使用。
2、锁的类型不同
await只能在实现了LockSupport接口的锁上使用,这些锁可以是ReentrantLock、ReentrantReadWriteLock等可重入锁,而wait则可以在任何类型的锁上使用,包括内置的synchronized方法和对象的wait()、notify()/notifyAll()方法。
3、释放锁的方式不同
await需要在finally块中释放锁,因为它使用的是Unsafe类的park方法,这个方法会在获取到锁后自动释放锁,而wait则需要手动调用Object类的notify或notifyAll方法来释放锁,如果在等待过程中发生异常并且没有在try-catch块中捕获,那么这个锁可能永远不会被释放。
4、阻塞方式不同
await是非阻塞的,它会立即返回,不会等待锁被释放,而wait则是阻塞的,它会一直等待,直到锁被释放或者超时。
5、使用场景不同
由于await和wait的使用场景不同,因此在实际编程中应根据需要选择合适的方法,如果需要在已经获取到锁的情况下执行一些操作,那么可以使用await;如果需要在等待某个条件满足时阻塞当前线程,那么可以使用wait。
相关问题与解答
问题1:在什么情况下应该使用await而不是wait?
答:在已经获取到锁的情况下执行一些操作时,应该使用await,因为await是非阻塞的,它可以立即返回,不会等待锁被释放,这样可以提高程序的并发性能,而在等待某个条件满足时阻塞当前线程的场景下,应该使用wait,因为wait是阻塞的,它可以确保线程在条件满足之前不会继续执行其他任务。
问题2:如何在自定义的LockSupport实现中使用await?
答:要在自定义的LockSupport实现中使用await,首先需要让该类实现LockSupport接口,在该类中定义一个unpark方法,该方法需要使用Unsafe类的park方法来唤醒等待在该LockSupport对象上的线程,在需要使用await的地方调用该unpark方法即可。
public class MyLockSupport extends LockSupport { private final ReentrantLock lock = new ReentrantLock(); @Override public void lock() { lock.lock(); } @Override public void unlock() { lock.unlock(); } public void await() throws InterruptedException { Thread t = Thread.currentThread(); while (!lock.hasQueuedThread(t)) { Thread.yield(); // 让出CPU时间片,避免CPU占用过高 } lock.unpark(t); // 唤醒等待在MyLockSupport对象上的线程 } }
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/151104.html