面试题答案
一键面试synchronized 代码块中线程 A 调用 sleep 方法
- 锁的处理机制:
- 当线程 A 在 synchronized 代码块中调用
sleep
方法时,线程 A 并不会释放它所持有的锁。sleep
方法只是让线程进入睡眠状态,暂停执行一段时间,但它仍然占有锁。 - 这是因为
sleep
是Thread
类的静态方法,它不涉及到对象监视器(锁)的操作。
- 当线程 A 在 synchronized 代码块中调用
- 对程序运行逻辑的影响:
- 线程 B 尝试获取该锁时,由于线程 A 仍然持有锁,线程 B 会被阻塞,进入阻塞队列等待。直到线程 A 从
sleep
中醒来,执行完 synchronized 代码块并释放锁,线程 B 才有机会获取锁并继续执行。 - 例如:
- 线程 B 尝试获取该锁时,由于线程 A 仍然持有锁,线程 B 会被阻塞,进入阻塞队列等待。直到线程 A 从
public class SleepInSync {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread A = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread A acquired the lock");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread A released the lock");
}
});
Thread B = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread B acquired the lock");
}
});
A.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
B.start();
}
}
在这个例子中,线程 A 获得锁后睡眠 2 秒,在这 2 秒内线程 B 尝试获取锁会被阻塞,直到线程 A 醒来释放锁,线程 B 才能获取锁并执行。
synchronized 代码块中线程 A 调用 wait 方法
- 锁的处理机制:
- 当线程 A 在 synchronized 代码块中调用
wait
方法时,线程 A 会释放它所持有的锁。wait
方法是Object
类的实例方法,它与对象监视器(锁)密切相关。 - 线程 A 调用
wait
后,会进入该对象的等待队列,等待其他线程调用notify
或notifyAll
方法唤醒它。
- 当线程 A 在 synchronized 代码块中调用
- 对程序运行逻辑的影响:
- 线程 B 尝试获取该锁时,由于线程 A 已经释放了锁,线程 B 有机会获取锁并继续执行。
- 例如:
public class WaitInSync {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread A = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread A acquired the lock");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread A released the lock");
}
});
Thread B = new Thread(() -> {
synchronized (lock) {
System.out.println("Thread B acquired the lock");
lock.notify();
}
});
A.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
B.start();
}
}
在这个例子中,线程 A 获得锁后调用 wait
释放锁并进入等待队列,线程 B 有机会获取锁,执行完后调用 notify
唤醒线程 A,线程 A 被唤醒后重新获取锁继续执行。
总结来说,sleep
方法不会释放锁,而 wait
方法会释放锁,这两种方法在多线程环境下对锁的处理和程序运行逻辑有显著不同。