锁定老帖子 主题:同一任务和对象锁的问题
精华帖 (0) :: 良好帖 (1) :: 新手帖 (9) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-04
最后修改:2010-08-04
问题是这样的:一般来说,在多线程程序中,某个任务在持有某对象的锁后才能运行任务,其他任务只有在该任务释放同一对象锁后才能拥有对象锁,然后执行任务。于是,想到,同一个任务在持有同一个对象的锁后,在不释放锁的情况下,继续调用同一个对象的其他同步(synchronized)方法,该任务是否会再次持有该对象锁呢? 答案是肯定的。同一个任务在调用同一个对象上的其他synchronized方法,可以再次获得该对象锁。 多线程编程是一件很微妙的事情,这里考验人的不是大局而是细节,细节的细节。希望能唤醒自己愚笨的思维。 package thread.thread1; /** * 同一任务可以再次持有对象锁 create on 2010.08.04 08:27 * * @since jdk1.6 * @author maozj * @version 1.0 * */ public class SynchronizedClassHolder { /** * Test client * @param args */ public static void main(String[] args) { new Thread() { public void run() { new SynchronizedClassHolder().f1(); } }.start(); } private static int count = 10; /** * synchronized f1() */ public synchronized void f1() { if (--count > 0) { System.out.println("f1() calling f2() count " + count); f2(); } } /** * synchronized f2() */ public synchronized void f2() { if (--count > 0) { System.out.println("f2() calling f1() count " + count); f1(); } } } 输出: f1() calling f2() count 9 f2() calling f1() count 8 f1() calling f2() count 7 f2() calling f1() count 6 f1() calling f2() count 5 f2() calling f1() count 4 f1() calling f2() count 3 f2() calling f1() count 2 f1() calling f2() count 1 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-08-04
期待高手讲解原理
|
|
返回顶楼 | |
发表时间:2010-08-04
我是这样理解的。 Java Monitors Are Reentrant 也就是当前线程如果已经有了一个Object a的锁,那么此线程想再次获取这个a的锁时,可以继续获取。然后在此线程对于该锁的计数上+1. 比如
synchronized m1(){ //加入此时对锁a的计数是N m2(); //进入m2的方法体之后锁计数是N+1,离开m2后是N } synchronized m2(){} 这样就能保证锁的正确获取和释放了。
个人理解,仅供参考~ |
|
返回顶楼 | |
发表时间:2010-08-04
嗯。深入java虚拟机中说:一个线程可以多次对同一个对象上锁。对于每一个对象,java虚拟机维护一个加锁计数器,线程每获得一次该对象,计数器就加1,每释放一次,计数器就减1,当计数器值为0时,锁就被完全释放了。
|
|
返回顶楼 | |
发表时间:2010-08-04
maozj 写道 同一个任务在调用同一个对象上的其他synchronized方法,可以再次获得该对象锁。
是这样的吗? 我一直认为是,已经持有锁了,可以继续执行synchronized方法。 不是你说的“可以再次获得该对象锁”。 |
|
返回顶楼 | |
发表时间:2010-08-04
hardPass 写道 maozj 写道 同一个任务在调用同一个对象上的其他synchronized方法,可以再次获得该对象锁。
是这样的吗? 我一直认为是,已经持有锁了,可以继续执行synchronized方法。 不是你说的“可以再次获得该对象锁”。 应该是采用的是引用计数的方法来实现的课重入。 |
|
返回顶楼 | |
发表时间:2010-08-04
hardPass 写道 maozj 写道 同一个任务在调用同一个对象上的其他synchronized方法,可以再次获得该对象锁。
是这样的吗? 我一直认为是,已经持有锁了,可以继续执行synchronized方法。 不是你说的“可以再次获得该对象锁”。 ------------------- 呵呵 你一直认为? |
|
返回顶楼 | |
发表时间:2010-08-04
最后修改:2010-08-04
每个对象有一个监视器对象,一个线程获取到该监视器以后。其它线程就只能进入该对象监视器的等待队列中,等待线程处于等待运行状态,等获取监视器的线程释放锁以后,从等待队列中激活一线程进行运行。。。
如果两个不同的同步方法,没有共享相同状态信息,考虑使用不同的监视器对象,也就是所说的拆分锁 |
|
返回顶楼 | |
发表时间:2010-08-04
把f1() f2()看作是2个对象,是不是更好解释一些?
|
|
返回顶楼 | |
发表时间:2010-08-04
简单来说,对象锁是可重入的,可重入针对的是每线程。
|
|
返回顶楼 | |