java 中的 wait 和 notify 实现的源码分析
2011-06-08 22:30
513 查看
在oracle JVM 1.6 里面实现的object的wait 和notify方法是在synchronizer.cpp里实现。
先介绍2个对象:
1. ObjectMonitor 对象 主要用来监视创立的Object
在synchronizer.cpp 里定义了,ObjectMonitor 的对象,我们来看ObjectMonitor的对象的结构体
每个object的对象里 markOop->monitor() 里可以保存ObjectMonitor的对象。
建立ObjectMonitor的算法:
如果不存在,可以向Thread 的ObjectMonitor 的对象列表中Allocate free objectMonitor 对象。
每个线程都有ObjectMonitor 的free和used的objectMonitor对象列表,如果没有free objectMonitor对象列表,将向global 中ListLock Allocate为了提高效率。
2. ObjectWaiter 对象
ObjectWaiter 对象
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方法里
先介绍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方法里
相关文章推荐
- Java的wait()、notify()学习三部曲之一:JVM源码分析
- java wait 和notify实现源码
- java并发包中的Condition和Lock 取代Synchronized、wait、notify/notifyAll实现线程的同步与互斥
- Java:使用wait()与notify()实现线程间协作
- java多线程解说【肆】_锁实现:wait()/notify()
- Java Collections Framework之Queue(LinkedList实现)源码分析(基于JDK1.6)
- Memcache分布式实现原理---Java_Memcache 源码分析
- java 中的wait和notify以及synchronized的使用,实现两个线程交替执行
- Java:使用wait()与notify()实现线程间协作
- Java基于微信公众号接口实现授权登录源码及原理分析
- java非并发容器ArrayList 和 LinkedList 优缺点比较及其实现源码分析
- (10) java源码分析 ---- HashMap源码分析 及其 实现原理分析
- Java Collections Framework之Stack源码分析缺陷,栈改进版(通过LinkedList实现)(基于JDK1.6)
- 从源码角度分析java 的 sleep()和wait()究竟有什么区别?
- Java:使用wait()与notify()实现线程间协作
- Java中HashMap底层实现原理(JDK1.8)源码分析
- JAVA源码剖析之---Object类(三)---toString,wait,notify,notifyAll,finalize方法的使用
- Java三线程按序打印10次ABC (Lock实现与synchronized,wait,notify实现)
- 转:【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
- Java:使用wait()与notify()实现线程间协作