返回信息流```Java
public class Widget {
public synchronized void doSomething(){
//...
}
}
class LoggingWidget extends Widget{
public synchronized void doSomething(){
System.out.println(toString()+":calling doSomething");
super.doSomething();
}
}
```
代码见上,对应对Java并发编程实践P21,书本上说,在构造子类对象后,调用doSomething方法时,每个doSomething方法在执行前都会获取Widget上的锁;我的问题是:从始至终不是只创建了子类LoggingWidget对象,锁不是应该属于子类对象LoggingWidget的?
这是一条镜像帖。来源:北邮人论坛 / java / #62304同步于 2019/7/10
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
【已解决】【问题】Java并发编程实践-重入机制树上问题
xiaoxiaohai
2019/7/10镜像同步15 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
子类方法用的是Loggingwidget的class对象的锁,父类获得的是widget的class对象的锁,是两个不同的锁
【 在 xiaoxiaohai (【意涵团】湖人总冠军~~) 的大作中提到: 】
: [md]
: ```Java
: public class Widget {
: ...................
测了一下,好像不是这样?
```java
public class test1 {
public static void main(String[] args) {
Base base = new Base();
son1 s1 = new son1();
son2 s2 = new son2();
for (int i = 0; i < 5; i++) {
new Thread(base::test).start();
}
for (int i = 0; i < 5; i++) {
new Thread(s2::test).start();
}
}
}
class Base {
public synchronized void test() {
String name = Thread.currentThread().getName();
System.out.println(name + " Base 111");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " Base 222");
}
}
class son1 extends Base {
}
class son2 extends Base {
@Override
public synchronized void test() {
String name = Thread.currentThread().getName();
System.out.println(name + " son2 111");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " son2 222");
}
}
```
```
Thread-0 Base 111
Thread-5 son2 111
Thread-0 Base 222
Thread-4 Base 111
Thread-5 son2 222
Thread-9 son2 111
Thread-4 Base 222
Thread-3 Base 111
Thread-9 son2 222
Thread-8 son2 111
Thread-3 Base 222
Thread-8 son2 222
Thread-2 Base 111
Thread-7 son2 111
Thread-2 Base 222
Thread-1 Base 111
Thread-7 son2 222
Thread-6 son2 111
Thread-1 Base 222
Thread-6 son2 222
```
【 在 xiaoxiaohai 的大作中提到: 】
: [md]
: ```Java
: public class Widget {
: ...................
【 在 winterddd 的大作中提到: 】
: syncheonized修饰的方法获取的是class对象的锁,不是类的实例对象的锁
1)当一个方法被synchronized修饰后,锁对象为当前方法所属对象,即方法中的this;
2)当一个静态方法被synchronized修饰后,该静态方法上锁的对象为当前类对象(Class类的实例)。每个类都有唯一的一个类对象。获取类对象的方式:类名.class。
现在是第一种情况,此时的锁不就是当前属于子类LoggingWidget类的对象吗?为何能称其类锁?
知乎上有你这个问题的回答,貌似是翻译的锅。
【 在 xiaoxiaohai 的大作中提到: 】
: [md]
: ```Java
: public class Widget {
: ...................
【 在 buyaogaosuta 的大作中提到: 】
: 知乎上有你这个问题的回答,貌似是翻译的锅。
: [upload=1][/upload]
:
既然评判标准就是“是不是当前实例”,而且由于JVM中只有创建了一个实例,那么得出结论:既然从始至终无父类实例的创建,那么也只能请求子类的锁,也就惊人的发现,书本上的说法是有失严谨的。
尽信书不如无书吗?
【 在 xiaoxiaohai 的大作中提到: 】
: 既然评判标准就是“是不是当前实例”,而且由于JVM中只有创建了一个实例,那么得出结论:既然从始至终无父类实例的创建,那么也只能请求子类的锁,也就惊人的发现,书本上的说法是有失严谨的。
: 尽信书不如无书吗?
书本来就不可能没错,何况还是翻译过来的
不过我有个疑问的是,实例锁其实锁的是对象头的markword,那么类锁锁的是什么呢?
虽然只创建子类,但父类和子类都是要加载的