wait源码实现如下//TRAPS表示是否有异常void ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) { if (UseBiasedLocking) { //如果是使用了偏向锁,要撤销偏向锁 BiasedLocking::revoke_and_rebias(obj, false, THREAD); assert(!obj->mark()->has_bias_pattern(), “biases should be revoked by now”); } …在biasedLocking.cpp中可以看到方法的实现。整体结构划分如下BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {//1:必须在安全点assert(!SafepointSynchronize::is_at_safepoint(), “must not be called while at safepoint”);//2:读取对象头markOop mark = obj->mark();if (mark->is_biased_anonymously() && !attempt_rebias) {//3:没有线程获取了偏向锁} else if (mark->has_bias_pattern()) {//4:已经偏向了}//5:没有执行偏向,通过启发式的方式决定到底是执行撤销还是执行rebiasHeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);if (heuristics == HR_NOT_BIASED) {//5.1:偏向状态改成了不需要偏向} else if (heuristics == HR_SINGLE_REVOKE) {//5.2:启发式决定执行单次的撤销}//6:等到虚拟机运行到safepoint,实际就是执行 VM_BulkRevokeBias 的doit的 bulk_revoke_or_rebias_at_safepoint方法VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD, (heuristics == HR_BULK_REBIAS), attempt_rebias);VMThread::execute(&bulk_revoke);return bulk_revoke.status_code();}没有获取偏向锁这里表示还没有被偏向,并且不是执行rebias// We are probably trying to revoke the bias of this object due to// an identity hash code computation. Try to revoke the bias// without a safepoint. This is possible if we can successfully// compare-and-exchange an unbiased header into the mark word of// the object, meaning that no other thread has raced to acquire// the bias of the object.markOop biased_value = mark;//prootype本身构建的是 markOop( no_hash_in_place | no_lock_in_place );markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());//执行CAS,如果当前对象的mark没有变更,就换成 unbiased_prototypemarkOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark);if (res_mark == biased_value) { //如果之前的和现在的一样,说明撤销成功,BIAS_REVOKED本身是一个枚举 return BIAS_REVOKED;}已经被其它线程获取了偏向//已经被线程偏向了,获取Klass对象,即类本身的头,obj则是它的实例 Klass* k = Klass::cast(obj->klass()); markOop prototype_header = k->prototype_header(); if (!prototype_header->has_bias_pattern()) { //对象当前的偏向状态已经过期,并且是不可偏向的,直接设置成已经撤销偏向即可 // This object has a stale bias from before the bulk revocation // for this data type occurred. It’s pointless to update the // heuristics at this point so simply update the header with a // CAS. If we fail this race, the object’s bias has been revoked // by another thread so we simply return and let the caller deal // with it. markOop biased_value = mark; markOop res_mark = (markOop) Atomic::cmpxchg_ptr(prototype_header, obj->mark_addr(), mark); assert(!((obj->mark_addr()))->has_bias_pattern(), “even if we raced, should still be revoked”); return BIAS_REVOKED; } else if (prototype_header->bias_epoch() != mark->bias_epoch()) { //实例的epoch和类本身的epoch值不一样,说明它已经过期,也就是说这个对象当前处于未偏向但是可偏向的状态(rebiasable) // The epoch of this biasing has expired indicating that the // object is effectively unbiased. Depending on whether we need // to rebias or revoke the bias of this object we can do it // efficiently enough with a CAS that we shouldn’t update the // heuristics. This is normally done in the assembly code but we // can reach this point due to various points in the runtime // needing to revoke biases. if (attempt_rebias) { //执行rebias wait希望直接撤销 assert(THREAD->is_Java_thread(), “”); markOop biased_value = mark; markOop rebiased_prototype = markOopDesc::encode((JavaThread) THREAD, mark->age(), prototype_header->bias_epoch()); markOop res_mark = (markOop) Atomic::cmpxchg_ptr(rebiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { //当前线程抢到了这个对象的偏向 return BIAS_REVOKED_AND_REBIASED; } } else { markOop biased_value = mark; markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); //CAS撤销偏向锁 markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark); if (res_mark == biased_value) { //撤销了偏向 return BIAS_REVOKED; } } }启发式策略//启发式的方式决定要做那种操作static HeuristicsResult update_heuristics(oop o, bool allow_rebias) { markOop mark = o->mark(); if (!mark->has_bias_pattern()) { //不可偏向直接返回 return HR_NOT_BIASED; } //控制撤销的次数 // Heuristics to attempt to throttle the number of revocations. // Stages: // 1. Revoke the biases of all objects in the heap of this type, // but allow rebiasing of those objects if unlocked. // 2. Revoke the biases of all objects in the heap of this type // and don’t allow rebiasing of these objects. Disable // allocation of objects of that type with the bias bit set. Klass* k = o->blueprint(); jlong cur_time = os::javaTimeMillis(); //获取上次执行bulk revication的时间 jlong last_bulk_revocation_time = k->last_biased_lock_bulk_revocation_time(); //获取执行bulk revocation的次数 int revocation_count = k->biased_lock_revocation_count(); //定义在globs.hpp,BiasedLockingBulkRebiasThreshold取值为20;BiasedLockingBulkRevokeThreshold取值为40,BiasedLockingDecayTime为25000毫秒 if ((revocation_count >= BiasedLockingBulkRebiasThreshold) && (revocation_count < BiasedLockingBulkRevokeThreshold) && (last_bulk_revocation_time != 0) && (cur_time - last_bulk_revocation_time >= BiasedLockingDecayTime)) { // This is the first revocation we’ve seen in a while of an // object of this type since the last time we performed a bulk // rebiasing operation. The application is allocating objects in // bulk which are biased toward a thread and then handing them // off to another thread. We can cope with this allocation // pattern via the bulk rebiasing mechanism so we reset the // klass’s revocation count rather than allow it to increase // monotonically. If we see the need to perform another bulk // rebias operation later, we will, and if subsequently we see // many more revocation operations in a short period of time we // will completely disable biasing for this type. //在执行了一定时间之内,执行的撤销次数没有超过阈值,那么认为可以优先执行bulk rebias,因此将计数回归原始值 k->set_biased_lock_revocation_count(0); revocation_count = 0; } // Make revocation count saturate just beyond BiasedLockingBulkRevokeThreshold if (revocation_count <= BiasedLockingBulkRevokeThreshold) { //计算执行撤销的次数 revocation_count = k->atomic_incr_biased_lock_revocation_count(); } if (revocation_count == BiasedLockingBulkRevokeThreshold) { //达到执行bulk revoke的阈值,执行bulk revoke return HR_BULK_REVOKE; } if (revocation_count == BiasedLockingBulkRebiasThreshold) { //达到 bulk rebias的阈值,执行bulk rebias return HR_BULK_REBIAS; } //默认执行单次的撤销 return HR_SINGLE_REVOKE;}bulk_revoke_or_rebias_at_safepointbulk revoke的关键在于它会遍历所有线程栈的每一帧static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o, bool bulk_rebias, bool attempt_rebias_of_object, JavaThread* requesting_thread) {…if (bulk_rebias) { … // Now walk all threads’ stacks and adjust epochs of any biased // and locked objects of this data type we encounter //遍历所有的线程for (JavaThread* thr = Threads::first(); thr != NULL; thr = thr->next()) { //遍历线程栈的每一帧,获取所有的监视器 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr); for (int i = 0; i < cached_monitor_info->length(); i++) { MonitorInfo* mon_info = cached_monitor_info->at(i); oop owner = mon_info->owner(); markOop mark = owner->mark(); if ((owner->klass() == k_o) && mark->has_bias_pattern()) { // We might have encountered this object already in the case of recursive locking assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, “error in bias epoch adjustment”); //更新所有栈中的有偏向锁的epoch owner->set_mark(mark->set_bias_epoch(cur_epoch)); } } }…// At this point we’re done. All we have to do is potentially// adjust the header of the given object to revoke its bias.revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread);}…if (attempt_rebias_of_object && o->mark()->has_bias_pattern() && klass->prototype_header()->has_bias_pattern()) { //bias_epoch本身则是表示获取了偏向锁 markOop new_mark = markOopDesc::encode(requesting_thread, o->mark()->age(), klass->prototype_header()->bias_epoch()); o->set_mark(new_mark);//执行rebiase status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED; …}}revoke_bias的执行如下static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {markOop mark = obj->mark();…//偏向锁的头markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);//非偏向锁的头markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);…//获取偏向的线程JavaThread* biased_thread = mark->biased_locker();if (biased_thread == NULL) { // Object is anonymously biased. We can get here if, for // example, we revoke the bias due to an identity hash code // being computed for an object. if (!allow_rebias) { //没有线程获取,又需要执行rebias,改掉对象头即可 obj->set_mark(unbiased_prototype); } … //撤销完毕 return BiasedLocking::BIAS_REVOKED;}…//线程活着//遍历栈帧,获取所有这个线程的监视器,按照最年轻到最老的顺序 GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(biased_thread); BasicLock* highest_lock = NULL; for (int i = 0; i < cached_monitor_info->length(); i++) { MonitorInfo* mon_info = cached_monitor_info->at(i); if (mon_info->owner() == obj) { … // Assume recursive case and fix up highest lock later //当前栈帧存在了这个对象的锁 markOop mark = markOopDesc::encode((BasicLock*) NULL); highest_lock = mon_info->lock(); //更新栈中的mark为NULL highest_lock->set_displaced_header(mark); }… } } if (highest_lock != NULL) { // Fix up highest lock to contain displaced header and point // object at it //将最久的那个lock更新为没有偏向 ,栈中 设置了锁记录 highest_lock->set_displaced_header(unbiased_prototype); // Reset object header to point to displaced mark //将对象头指向栈中的位置,这样表示就没有偏向了obj->set_mark(markOopDesc::encode(highest_lock)); assert(!obj->mark()->has_bias_pattern(), “illegal mark state: stack lock used bias bit”); … } else { … if (allow_rebias) { obj->set_mark(biased_prototype); } else { // Store the unlocked value into the object’s header. obj->set_mark(unbiased_prototype); } }//撤销完毕 return BiasedLocking::BIAS_REVOKED;}