加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Java 中的 wait 和 notify 达成的源码分析

发布时间:2021-11-24 17:25:24 所属栏目:PHP教程 来源:互联网
导读:在Oracle JVM 1.6 里面实现的object的wait 和notify方法是在synchronizer.cpp里实现。 先介绍2个对象: 1. ObjectMonitor 对象 主要用来监视创立的Object 在synchronizer.cpp 里定义了,ObjectMonitor 的对象,我们来看ObjectMonitor的对象的结构体 ObjectMo

在Oracle JVM 1.6 里面实现的object的wait 和notify方法是在synchronizer.cpp里实现。
 
先介绍2个对象:
 
1. ObjectMonitor  对象 主要用来监视创立的Object
 
在synchronizer.cpp 里定义了,ObjectMonitor 的对象,我们来看ObjectMonitor的对象的结构体
 
ObjectMonitor::ObjectMonitor() {  
  _header       = NULL;  
  _count        = 0;  
  _waiters      = 0,  
  _recursions   = 0;  
  _object       = NULL;  
  _owner        = NULL;  
  _WaitSet      = NULL;  
  _WaitSetLock  = 0 ;  
  _Responsible  = NULL ;  
  _succ         = NULL ;  
  _cxq          = NULL ;  
  FreeNext      = NULL ;  
  _EntryList    = NULL ;  
  _SpinFreq     = 0 ;  
  _SpinClock    = 0 ;  
  OwnerIsThread = 0 ;  
}  
每个object的对象里 markOop->monitor() 里可以保存ObjectMonitor的对象。
 
建立ObjectMonitor的算法:
 
如果不存在,可以向Thread 的ObjectMonitor 的对象列表中Allocate free objectMonitor 对象。
 
每个线程都有ObjectMonitor 的free和used的objectMonitor对象列表,如果没有free objectMonitor对象列表,将向global 中ListLock Allocate为了提高效率。
 
2.  ObjectWaiter 对象
 
ObjectWaiter 对象
 
class ObjectWaiter : public StackObj {  
 public:  
  enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ } ;  
  enum Sorted  { PREPEND, APPEND, SORTED } ;  
  ObjectWaiter * volatile _next;  
  ObjectWaiter * volatile _prev;  
  Thread*       _thread;  
  ParkEvent *   _event;  
  volatile int  _notified ;  
  volatile TStates TState ;  
  Sorted        _Sorted ;           // List placement disposition   
  bool          _active ;           // Contention monitoring is enabled   
 public:  
  ObjectWaiter(Thread* thread) {  
    _next     = NULL;  
    _prev     = NULL;  
    _notified = 0;  
    TState    = TS_RUN ;  
    _thread   = thread;  
    _event    = thread->_ParkEvent ;  
    _active   = false;  
    assert (_event != NULL, "invariant") ;  
  }  
  void wait_reenter_begin(ObjectMonitor *mon) {  
    JavaThread *jt = (JavaThread *)this->_thread;  
    _active = JavaThreadBlockedOnMonitorEnterState::wait_reenter_begin(jt, mon);  
  }  
  void wait_reenter_end(ObjectMonitor *mon) {  
    JavaThread *jt = (JavaThread *)this->_thread;  
    JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active);  
  }  
};  
ObjectWaiter 对象里存放thread(线程对象) 和 ParkEvent(线程的unpark), 每一个等待锁的线程都会有一个ObjectWaiter对象.
 
而objectwaiter是个双向链表结构的对象。
 
我们可以看到在ObjectMonitor对象里有2个队列成员_WaitSet 和 _EntryList 存放的就是ObjectWaiter
 
_WaitSet:
 
主要存放所有wait的线程的对象,也就是说如果有线程处于wait状态,将被挂入这个队列
 
_EntryList:
 
所有在等待获取锁的线程的对象,也就是说如果有线程处于等待获取锁的状态的时候,将被挂入这个队列。
 
Wait 方法实现:
 
ObjectSynchronizer::wait方法
 
通过object的对象中找到ObjectMonitor对象
 
调用方法
 
void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS)
 
通过ObjectMonitor::AddWaiter调用把新建立的ObjectWaiter对象放入到 _WaitSet 的队列的末尾中
 
然后在ObjectMonitor::exit释放锁,接着 thread_ParkEvent->park  也就是wait
 
Notify方法的实现:
 
ObjectSynchronizer::notify方法
 
调用ObjectSynchronizer::inflate
 
object的对象中找到ObjectMonitor对象
 
然后调用方法ObjectMonitor::notify
 
调用ObjectMonitor::DequeueWaiter 摘除第一个ObjectWaiter对象从_WaitSet 的队列中
 
并把这个ObjectWaiter对象放入_EntryList中,_EntryList 存放的是ObjectWaiter的对象列表,列表的大小就是那些所有在等待这个对象锁的线程数。
 
注意这里并没有调用ObjectMonitor::exit释放锁
 
NotifyALL和Notify 的区别就是
 
通过遍历调用ObjectMonitor::DequeueWaiter,把所有的_WaitSet的队列中的ObjectWaiter对象放入到_EntryList中
 
关于放入到_EntryList的策略大概有4中Policy,其中还涉及到一个_cxq的队列,先不具体介绍了
 
notify, 和notifyAll 都没有释放对象的锁,而是在Synchronizer同步块结束的时候释放
 
如何释放锁
 
调用ObjectMonitor::exit
 
从_EntryList里找到一个ObjectWaiter,因为ObjectWaiter里有线程的_event ParkEvent,调用unpark() 通知ObjectWaite里的线程运行(拿到锁),具体实现在ObjectMonitor::ExitEpilog方法里

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读