阅读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获取锁,打印程序的唯一输出,然后释放锁。
主线程获取一个锁,通知一个等待的线程,然后释放锁。
因此,线程可以按照几个顺序获取锁,所有这些顺序都会产生相同的输出。
您的问题">代码显示只需要一次锁定操作,或者我缺少了什么?"已由@Pete Kirkham回答。
主要问题">在Java中多次锁定的对象需要多少次解锁操作才能解锁?"的答案就是您引用的答案。
以下代码显示Thread t1
如何">多次锁定特定监视器"以及"每次解锁都会逆转一次锁定操作的效果。"。
CCD_ 2进入CCD_ 3块三次。每次进入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为我运行。