2007-09-09
在处理同步问题上产生的疑惑
本来我一直以为synchronized是把当前this对象和方法绑定起来锁定方法,实现资源共享中线程安全机制,当方法执行完成之后锁被释放,直到下面的例子产生了疑惑 如果是上述结果的话,那么锁住的不仅仅是当前调用的这个方法,只要是被注明synchronized关键字的所有方法在未运行时就都被锁定了,然而我有编辑下面一个例子,证明了我的想法又是错误的
java 代码
- public class A{
- public synchronized void do1() throws Exception{
- System.out.println("do1 enter");
- Thread.sleep(2000);
- System.out.println("do1 end");
- }
- public synchronized void do2() throws Exception{
- System.out.println("do2 enter");
- System.out.println("do2 end");
- }
- public static void main(String[] args){
- final A obj=new A();
- new Thread(){
- public void run(){
- try {
- obj.do1();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }.start();
- new Thread(){
- public void run(){
- try {
- obj.do2();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }.start();
- }
- }
运行结果是
do1 enter
do1 end
do2 enter
do2 end
java 代码
- public class B {
- public synchronized void fun1(){
- System.out.println("fun1() is invoked");
- fun2();
- }
- public synchronized void fun2(){
- System.out.println("fun2() is invoked");
- }
- public static void main(String[] args) {
- B obj=new B();
- obj.fun1();
- }
- }
运行结果是
fun1() is invoked
fun2() is invoked
如果采用上一个例子中的经验,那么这个类B应该是在未运行时锁住了该OBJ实例中的两个方法,刚进入fun1()时把当前this对象锁住了,但是应该无法运行fun2(),因为fun2()无法在fun1()没有释放锁的情况下再次获得锁,应该失去了活跃性,造成dead lock,但这里为什么会正常运行了,同步机制到底锁的什么?如果其中两个方法加了synchronized关键字,在多线程环境中能不能同时被调用?请一下
评论
galaxystar
2007-09-10
楼主可以研究下 jdk1.5的 reentrantLock, 以及同步器 abstractQueuedSynchronizer
andy_java
2007-09-09
dennis_zane 写道
andy_java 写道
dennis_zane 写道
第二段代码中,主线程运行fun1(),请求了锁,fun1()中要调用fun2(),仍然是同一个线程内,仅仅是这个锁关联的计数+1,仍然可以获得锁,原因如上所述。
是不是说明了多线程环境中锁的是当前对象下的所有的同步方法,而单线程环境中锁的是当前调用的方法?要理解这句话:对锁的请求是基于每个线程,而不是每个调用。多线程环境下,某个线程1方法1请求一个锁A,那么其他线程要获得锁A就要等待,线程1中方法1中如果再次请求锁A,锁是可重进入的,且是同一个线程,那么方法1中的请求获得通过,并且锁关联的计数+1,此时其他线程要想获得锁A仍然要等待线程1释放两次锁A了(因为请求了两次,同一个线程内可重复请求)
这是不是线程的默认机制?同步块是不是也采用这个机制?请楼上的高手再讲解一下:)
dennis_zane
2007-09-09
andy_java 写道
dennis_zane 写道
第二段代码中,主线程运行fun1(),请求了锁,fun1()中要调用fun2(),仍然是同一个线程内,仅仅是这个锁关联的计数+1,仍然可以获得锁,原因如上所述。
是不是说明了多线程环境中锁的是当前对象下的所有的同步方法,而单线程环境中锁的是当前调用的方法?要理解这句话:对锁的请求是基于每个线程,而不是每个调用。多线程环境下,某个线程1方法1请求一个锁A,那么其他线程要获得锁A就要等待,线程1中方法1中如果再次请求锁A,锁是可重进入的,且是同一个线程,那么方法1中的请求获得通过,并且锁关联的计数+1,此时其他线程要想获得锁A仍然要等待线程1释放两次锁A了(因为请求了两次,同一个线程内可重复请求)
andy_java
2007-09-09
dennis_zane 写道
第二段代码中,主线程运行fun1(),请求了锁,fun1()中要调用fun2(),仍然是同一个线程内,仅仅是这个锁关联的计数+1,仍然可以获得锁,原因如上所述。
是不是说明了多线程环境中锁的是当前对象下的所有的同步方法,而单线程环境中锁的是当前调用的方法?
dennis_zane
2007-09-09
第二段代码中,主线程运行fun1(),请求了锁,fun1()中要调用fun2(),仍然是同一个线程内,仅仅是这个锁关联的计数+1,仍然可以获得锁,原因如上所述。
dennis_zane
2007-09-09
很简单,因为锁是可重进入的(Reentrancy),对锁的请求是基于每个线程,而不是每个调用。
andy_java
2007-09-09
"如果是上述结果的话,那么锁住的不仅仅是当前调用的这个方法,只要是被注明synchronized关键字的所有方法在未运行时就都被锁定了,然而我有编辑下面一个例子,证明了我的想法又是错误的"
这段话是用来解释第一段代码的
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 990 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
在处理同步问题上产生的疑 ...
楼主可以研究下 jdk1.5的 reentrantLock, 以及同步器 abs ...
-- by galaxystar -
在处理同步问题上产生的疑 ...
dennis_zane 写道andy_java 写道dennis_zane 写道 ...
-- by andy_java -
在处理同步问题上产生的疑 ...
andy_java 写道dennis_zane 写道第二段代码中,主线程运行fu ...
-- by dennis_zane -
在处理同步问题上产生的疑 ...
dennis_zane 写道第二段代码中,主线程运行fun1(),请求了锁,fu ...
-- by andy_java -
在处理同步问题上产生的疑 ...
第二段代码中,主线程运行fun1(),请求了锁,fun1()中要调用fun2() ...
-- by dennis_zane






评论排行榜