`
xieyj
  • 浏览: 99910 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

openjdk中的同步代码

阅读更多

        在java虚拟机中的方法同步synchronized,是通过使用monitorenter和monitorexit这两个操作码,当虚拟机遇到monitorenter的时候,它会获得栈中objectref所引用的对象的锁。如果线程已经拥有那个对象的锁,锁的计数器加1,线程中每个monitorexit会引起计数器减1,当计数器为0时候,监视器就释放了。

         先看看openjdk中的monitorenter代码(bytecodeInterpreter.cpp)

         {

                   if (entry != NULL) {  //获取一个空闲的监视器

                             entry->set_obj(lockee);
                             markOop displaced = lockee->mark()->set_unlocked();
                             entry->lock()->set_displaced_header(displaced);
                             if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { 

                                    if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
                                             entry->lock()->set_displaced_header(NULL);
                                    } else {
                                              CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
                                    }
                             }
                             UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
                    } else { //监视器为空,重试
                      istate->set_msg(more_monitors);
                      UPDATE_PC_AND_RETURN(0); // Re-execute
                  }

         }

        看一下InterpreterRuntime::monitorenter,

        void InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem){

                  .......

                  Handle h_obj(thread, elem->obj());

                  ObjectSynchronizer::slow_enter(h_obj, elem->lock(), CHECK);

        }

        slow_enter调用下面的inflate

        ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) {

                   for (;;) {
                              const markOop mark = object->mark() ;

                              /*

                               mark有几种状态,inflated直接返回,Stack-locked转换为inflated,

                               INFLATING 不断等待直到完成,Neutral 锁升级?

                              */

                              //inflated 状态

                              if (mark->has_monitor()) { //已经获得锁,直接返回
                                     ObjectMonitor * inf = mark->monitor() ;
                                      return inf ;
                              }

                             

                              if (mark == markOopDesc::INFLATING()) {
                                       ReadStableMark(object) ;  //不断检测,超过一定次数睡眠
                                       continue ;
                              }

                              //stack locked 状态

                              if (mark->has_locker()) {
                                      ObjectMonitor * m = omAlloc (Self) ;
                                      markOop cmp = (markOop) Atomic::cmpxchg_ptr (markOopDesc::INFLATING(), object->mark_addr(), mark) ;   //将object->mark_addr()和mark比较,如果这两个值相等,则将object->mark_addr()改成markOopDesc::INFLATING(),值比较相等返回是mark,不相等返回的是object->mark_addr(), 比较和赋值是一个原子操作
                                       if (cmp != mark) { //不断检测值,自旋锁的用法
                                                    omRelease (Self, m) ;
                                                     continue ;       // 重新进行循环                                      

                                       }

                                       markOop dmw = mark->displaced_mark_helper() ;

                                       m->set_header(dmw) ; //设置mark->has_monitor()?也就是inflated 状态

                                       ...............

                                       return m ;

                             }

                             //Neutral状态

                              m->set_header(mark);

                             if (Atomic::cmpxchg_ptr (markOopDesc::encode(m), object->mark_addr(), mark) != mark) {//在此又做了一次检测,到底是何目的?
                                          continue ;
                            }

                             ............

                             if (_sync_Inflations != NULL) _sync_Inflations->inc() ; //增加计数

                             return m ;

                  }

        }

        整个获取锁的过程十分复杂,大大超出我的预料,大概是为了避免死锁这些,所以才设计了这么复杂,象是采用锁升级这种技术,锁的这几种状态是干什么用的,现在还弄不很清楚。

1
0
分享到:
评论
1 楼 hatedance 2012-02-01  
这个bytecodeInterpreter应该已经被遗弃了,现在都改用templateinterpreter了。

相关推荐

Global site tag (gtag.js) - Google Analytics