论坛首页 Java企业应用论坛

Java Concurrency in Practice疑问

浏览 5411 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-03-03  
最近在拜读Java Concurrency in Practice
有一处不理解的地方,还请群里的大牛们不吝赐教~
Reentrancy facilitates encapsulation of locking behavior, and thus simplifies the development of object-oriented concurrent code. Without reentrant locks, the very natural-looking code in Listing 2.7, in which a subclass overrides a synchronized method and then calls the superclass method, would deadlock. Because the doSomething methods in Widget and LoggingWidget are both synchronized, each tries to acquire the lock on the Widget before proceeding. But if intrinsic locks were not reentrant, the call to super.doSomething would never be able to acquire the lock because it would be considered already held, and the thread would permanently stall waiting for a lock it can never acquire.
翻译过来大致是这样的:
可重入性封装了获取锁的行为,并且也简化了面向对象式并发代码的开发。如果没有可重入性,2.7中很自然的代码(子类重写了父类的同步方法,并且在重写后的方法内又调用了父类的这一同步方法)将会造成死锁。因为,Widget类和LoggingWidget类中的doSomething方法都是同步的,他们各自在处理前都尝试去获取Widget的锁。但是如果锁不是可重入的,那么super.doSomething这段代码将永远不能获取锁,因为这个锁被认为已经持有了,于是这个线程将永久的等待一个不可能获取得到的锁。
Listing 2.7
public class Widget {
    public synchronized void doSomething() {
        ...
    }
}
public class LoggingWidget extends Widget {
    public synchronized void doSomething() {
        System.out.println(toString() + ": calling doSomething");
        super.doSomething();
    }
}

问题:(红线部分)
1.当调用LoggingWidget的doSomething方法时,如果没有可重入性,获取锁的步骤的怎样的,为什么会死锁?LoggingWidget对象的锁和Widget的锁有什么关系?
2.第二段红线部分,“这个锁被认为已经持有了”,是被谁持有了?是当前获取了LoggingWidget对象锁的这一线程吗?
   发表时间:2012-03-03   最后修改:2012-03-03
引用
1.当调用LoggingWidget的doSomething方法时,如果没有可重入性,获取锁的步骤的怎样的,为什么会死锁?LoggingWidget对象的锁和Widget的锁有什么关系?



可重入,个人理解意思是:同一个线程同一时刻持有同一把锁的次数可超过1

首先,对象只有一个,锁该只有一把,LoggingWidget#doSomething持有锁后,在调用到Widget#doSomething的时候,还需要这把锁,如果不可重入,Widget#doSomething永远也拿不到那把锁,因为同一时刻持有同一把锁的次数超过1了,于是,就产生了一种饥饿状态




引用
2.第二段红线部分,“这个锁被认为已经持有了”,是被谁持有了?是当前获取了LoggingWidget对象锁的这一线程吗?


个人认为可以这么理解吧
0 请登录后投票
   发表时间:2012-03-04  
freish 写道
引用
1.当调用LoggingWidget的doSomething方法时,如果没有可重入性,获取锁的步骤的怎样的,为什么会死锁?LoggingWidget对象的锁和Widget的锁有什么关系?



可重入,个人理解意思是:同一个线程同一时刻持有同一把锁的次数可超过1

首先,对象只有一个,锁该只有一把,LoggingWidget#doSomething持有锁后,在调用到Widget#doSomething的时候,还需要这把锁,如果不可重入,Widget#doSomething永远也拿不到那把锁,因为同一时刻持有同一把锁的次数超过1了,于是,就产生了一种饥饿状态




引用
2.第二段红线部分,“这个锁被认为已经持有了”,是被谁持有了?是当前获取了LoggingWidget对象锁的这一线程吗?


个人认为可以这么理解吧


谢谢!想了很久终于明白了!以为不会有人来回答了呢...
0 请登录后投票
   发表时间:2012-03-05  
    Listing 2.7  
    public class Widget {  
        public synchronized void doSomething() {  
            ...  
        }  
    }  
    public class LoggingWidget extends Widget {  
        public synchronized void doSomething() {  
            System.out.println(toString() + ": calling doSomething");  
            super.doSomething();  
        }  
    }  


以java上代码在同一个线程执行时,不会导致死锁,java中的synchronized 本身就是可以重入的(reentrant),不是吗? 不管是synchronized方法,还是synchronized statements。参见:
http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
http://stackoverflow.com/questions/5787957/reentrant-synchronization-behavior-with-synchronized-statements
0 请登录后投票
   发表时间:2012-03-05  
求《Java Concurrency in Practice》的电子版,纸质的好像也没卖了咯,不知道楼主在那搞的?
0 请登录后投票
   发表时间:2012-03-05  
ivin 写道
求《Java Concurrency in Practice》的电子版,纸质的好像也没卖了咯,不知道楼主在那搞的?

京东商城有卖的了,今年2月份重新翻译的中文版。
0 请登录后投票
   发表时间:2012-03-05  
ivin 写道
求《Java Concurrency in Practice》的电子版,纸质的好像也没卖了咯,不知道楼主在那搞的?


我的是英文chm版 要的话 把你邮箱站内信发我哈~
0 请登录后投票
   发表时间:2012-03-05  
haohouhou 写道
ivin 写道
求《Java Concurrency in Practice》的电子版,纸质的好像也没卖了咯,不知道楼主在那搞的?

京东商城有卖的了,今年2月份重新翻译的中文版。


据说翻译的很烂...
0 请登录后投票
   发表时间:2012-03-06  
皮皮书屋上有 中文版的。
0 请登录后投票
   发表时间:2012-03-06  
http://www.blogjava.net/chenpengyi/archive/2007/10/18/153977.html
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics