Java Condition面试题
1. 什么是Condition?
Condition是Java中用于线程间通信的一个同步辅助类,它与Lock一起使用,允许一个或多个线程等待某个条件成立。
2. Condition和wait/notify有什么区别?
Condition提供了比wait/notify更灵活的线程间通信机制,可以有多个Condition对象,每个对象可以独立控制线程的等待和唤醒。
3. 如何使用Condition实现等待/通知机制?
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
notFull.await();
}
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0) {
notEmpty.await();
}
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
4. Condition的await()方法有什么作用?
await()
方法使当前线程等待,直到其他线程调用相同Condition对象的signal()或signalAll()方法。
5. Condition的signal()和signalAll()方法有什么区别?
signal()
方法唤醒等待队列中的第一个线程,而signalAll()
方法唤醒等待队列中的所有线程。
6. Condition如何与Lock一起使用?
必须在获取了Lock的情况下才能调用Condition的await()、signal()或signalAll()方法。
7. Condition的await()方法可以响应中断吗?
是的,await()
方法可以响应中断,如果线程在等待过程中被中断,会抛出InterruptedException异常。
8. Condition的awaitUninterruptibly()方法有什么作用?
awaitUninterruptibly()
方法与await()
类似,但它不会响应中断,即使线程被中断也不会抛出异常。
9. Condition的awaitNanos()方法有什么作用?
awaitNanos()
方法尝试等待直到被唤醒或超过指定的等待时间,返回剩余的等待时间或0。
10. Condition的awaitUntil()方法有什么作用?
awaitUntil()
方法尝试等待直到被唤醒或超过指定的时间戳,返回false
如果超时,true
如果被唤醒。
11. Condition的等待队列和同步队列有什么区别?
等待队列是Condition对象维护的队列,用于存放调用await()方法的线程。同步队列是AQS维护的队列,用于存放尝试获取锁的线程。
12. Condition的await()方法可以被中断吗?
是的,await()
方法可以被中断,如果当前线程在等待过程中被中断,会抛出InterruptedException异常。
13. Condition的await()方法如何正确使用?
必须在try-finally块中使用await()
方法,并确保在finally块中释放锁。
14. Condition的signal()方法唤醒线程的顺序是怎样的?
signal()
方法唤醒等待队列中的第一个线程,按照它们等待的顺序。
15. Condition的signalAll()方法唤醒线程的顺序是怎样的?
signalAll()
方法唤醒等待队列中的所有线程,按照它们等待的顺序。
16. Condition的await()方法可以设置超时时间吗?
是的,await()
方法可以设置超时时间,如果超过指定时间没有被唤醒,则返回false
。
17. Condition的awaitUntil()方法和awaitNanos()方法有什么区别?
awaitUntil()
方法接受一个时间戳参数,而awaitNanos()
方法接受一个超时时间(纳秒)参数。
18. Condition的await()方法和LockSupport.park()方法有什么区别?
await()
方法是Condition对象提供的方法,用于等待某个条件成立,而LockSupport.park()
方法是一个更底层的方法,用于阻塞当前线程。
19. Condition的await()方法和Object的wait()方法有什么区别?
await()
方法需要在获取了Lock的情况下调用,而wait()
方法是Object类的方法,需要在获取了对象的监视器(monitor)的情况下调用。
20. Condition的await()方法可以被多个线程同时调用吗?
可以,多个线程可以同时调用同一个Condition对象的await()
方法。
21. Condition的await()方法如何确保线程安全?
await()
方法是线程安全的,因为它需要在获取了Lock的情况下调用,并且Condition对象与Lock对象紧密关联。
22. Condition的await()方法可以被重入吗?
不可以,await()
方法不能被重入,因为重入会导致锁的嵌套,而Condition对象不支持锁的重入。
23. Condition的await()方法和synchronized块有什么区别?
await()
方法提供了更灵活的线程间通信机制,可以有多个Condition对象,而synchronized块只能有一个监视器。
24. Condition的await()方法可以被中断吗?
是的,await()
方法可以被中断,如果线程在等待过程中被中断,会抛出InterruptedException异常。
25. Condition的await()方法和LockSupport.park()方法可以一起使用吗?
不建议一起使用,因为它们的作用域不同,await()
方法是Condition对象的方法,而LockSupport.park()
方法是更底层的方法。