java - 在 Java 中解锁多次锁定的对象需要多少次解锁操作?
问题描述
阅读 java 语言规范 - 内存模型我发现了这个说法。
一个线程 t 可能会多次锁定一个特定的监视器;每次解锁都会反转一次锁定操作的效果。
然后我使用下面的代码尝试了这个,但是它似乎不起作用。要么我不理解该声明,要么我的代码没有按照我的意愿行事......
public class MultipleLocks {
private static final Object LOCK = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (LOCK) {
//some code ...
}
}
synchronized (LOCK) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
Thread t2 = new Thread(() -> {
synchronized (LOCK) {
System.out.println("I can acquire a lock !");
}
});
t2.start();
synchronized (LOCK) {
LOCK.notify();
}
}
}
11 - 锁只解锁一次?
代码显示只需要一次锁定操作,还是我遗漏了什么?
编辑:
如果我的代码错误,我如何模拟获取锁 n 次并释放它 n 次,如果 n-1 次被释放,那么线程应该继续锁定锁?
解决方案
此代码没有对对象的状态做任何事情:
for (int i = 0; i < 10; i++) {
synchronized (LOCK) { // lock gained on LOCK object
//some code ...
} // lock released on LOCK object
}
锁在同步块开始时获得并在结束时释放。这样做十次会使对象处于与循环开始时相同的状态。
Thread1 然后获取锁然后等待,这导致它释放锁,直到另一个线程通知对象。
线程释放此监视器的所有权并等待,直到另一个线程通知等待此对象监视器的线程唤醒 Object.wait() javadocs
Thread2 获取锁,打印程序的唯一输出,然后释放锁。
主线程获取锁,通知一个等待线程,然后释放锁。
因此,线程可以通过多种顺序获取锁,所有这些都会产生相同的输出。
推荐阅读
- r - R中不同维度数据框的相关性测试
- java - 如何将 bash 脚本的输出打印到 Java 标准输出
- javascript - 自动填充输入
- angular - FxFill 在 5.0.0-beta.14 更新中无法正常工作
- javascript - 检测正在加载到 DOM 中的新图像,jQuery 加载事件处理程序不会触发
- python - 在枕头库中,BICUBIC 不工作
- javascript - 如何将数据从 Javascript 传递到 PHP Laravel?
- laravel - 我应该为不同的用户类型设置不同的表吗
- angular - 在 Godaddy 上托管应用程序后图像未加载
- gtk - Gtk.Stack 不会更改事件回调函数中的可见子项