阅读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次释放,则线程应继续锁定该锁?
答案 0 :(得分:2)
此代码对对象的状态没有任何作用:
x
该锁在同步块的开始处获得,并在结束时释放。这样做十次,使对象保持与循环开始时相同的状态。
然后,Thread1获取锁,然后等待,这导致它释放锁,直到另一个线程通知该对象。
线程释放该监视器的所有权,并等待直到另一个 线程通知在此对象的监视器上等待唤醒的线程 Object.wait() javadocs
Thread2获取一个锁,打印程序的唯一输出,然后释放该锁。
主线程获取一个锁,通知一个正在等待的线程,然后释放该锁。
因此,线程可以按几种顺序获取锁,所有这些都导致相同的输出。
答案 1 :(得分:1)
您的问题“ 代码显示仅需要执行一次锁定操作,或者我缺少某些内容?”已由@Pete Kirkham回答。
您引用的主要问题“ 要对用Java多次锁定的对象进行解锁需要多少次解锁操作?”的答案。
以下代码显示了Thread t1
“ 多次锁定一个特定的显示器”和“ 每次解锁会反转一次锁定操作的效果”的方式。< / p>
Thread t1
进入synchronize
块三次。每当输入synchronize
块时,都需要一个(附加)锁。每次留下synchronize
块时,都会释放一个锁。因此,t1
离开后,所有synchronize
块Thread t2
首先可以进入synchronize
块。
public class Locking {
private static Object o = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(Locking::lockSeveralTimes);
Thread t2 = new Thread(Locking::lockOnce);
t1.start();
Thread.sleep(100); // give t1 some time to start
t2.start();
}
protected static void lockOnce() {
synchronized (o) {
System.out.println("DONE");
}
}
protected static void lockSeveralTimes() {
try {
System.out.println("Has Lock: " + Thread.holdsLock(o));
synchronized (o) {
System.out.println("Aquired Lock: " + Thread.holdsLock(o) + " / Times: " + getLockedMonitorsCount());
waitOneSecond();
synchronized (o) {
System.out.println("Aquired Lock: " + Thread.holdsLock(o) + " / Times: " + getLockedMonitorsCount());
waitOneSecond();
synchronized (o) {
System.out.println("Aquired Lock: " + Thread.holdsLock(o) + " / Times: " + getLockedMonitorsCount());
waitOneSecond();
System.out.println("Going to release lock. Still holds: " + Thread.holdsLock(o) + " / Times: " + getLockedMonitorsCount());
}
waitOneSecond();
System.out.println("Going to release lock. Still holds: " + Thread.holdsLock(o) + " / Times: " + getLockedMonitorsCount());
}
waitOneSecond();
System.out.println("Going to release lock. Still holds: " + Thread.holdsLock(o) + " / Times: " + getLockedMonitorsCount());
}
System.out.println("Still holds: " + Thread.holdsLock(o));
} catch (Exception e) {
e.printStackTrace();
}
}
protected static void waitOneSecond() throws InterruptedException {
Thread.sleep(1000);
}
protected static int getLockedMonitorsCount() {
return ManagementFactory.getThreadMXBean().getThreadInfo(new long[] { Thread.currentThread().getId() }, true, false)[0].getLockedMonitors().length;
}
}
输出为:
Has Lock: false
Aquired Lock: true / Times: 1
Aquired Lock: true / Times: 2
Aquired Lock: true / Times: 3
Going to release lock. Still holds: true / Times: 3
Going to release lock. Still holds: true / Times: 2
Going to release lock. Still holds: true / Times: 1
Still holds: false
DONE
使用JDK 8为我运行。