java 线程 防止_java是如何防止两个线程同时进入synchronzed同步块的?

// lock method if synchronized if (METHOD->is_synchronized()) {

// oop rcvr = locals[0].j.r; oop rcvr;

if (METHOD->is_static()) {

rcvr = METHOD->constants()->pool_holder()->java_mirror();

} else {

rcvr = LOCALS_OBJECT(0);

VERIFY_OOP(rcvr);

}

// The initial monitor is ours for the taking BasicObjectLock* mon = &istate->monitor_base()[-1];

oop monobj = mon->obj();

assert(mon->obj() == rcvr, "method monitor mis-initialized");

bool success = UseBiasedLocking;

if (UseBiasedLocking) {

markOop mark = rcvr->mark();

if (mark->has_bias_pattern()) {

// The bias pattern is present in the object's header. Need to check // whether the bias owner and the epoch are both still current. intptr_t xx = ((intptr_t) THREAD) ^ (intptr_t) mark;

xx = (intptr_t) rcvr->klass()->prototype_header() ^ xx;

intptr_t yy = (xx & ~((int) markOopDesc::age_mask_in_place));

if (yy != 0 ) {

// At this point we know that the header has the bias pattern and // that we are not the bias owner in the current epoch. We need to // figure out more details about the state of the header in order to // know what operations can be legally performed on the object's // header.

// If the low three bits in the xor result aren't clear, that means // the prototype header is no longer biased and we have to revoke // the bias on this object.

if (yy & markOopDesc::biased_lock_mask_in_place == 0 ) {

// Biasing is still enabled for this data type. See whether the // epoch of the current bias is still valid, meaning that the epoch // bits of the mark word are equal to the epoch bits of the // prototype header. (Note that the prototype header's epoch bits // only change at a safepoint.) If not, attempt to rebias the object // toward the current thread. Note that we must be absolutely sure // that the current epoch is invalid in order to do this because // otherwise the manipulations it performs on the mark word are // illegal. if (yy & markOopDesc::epoch_mask_in_place == 0) {

// The epoch of the current bias is still valid but we know nothing // about the owner; it might be set or it might be clear. Try to // acquire the bias of the object using an atomic operation. If this // fails we will go in to the runtime to revoke the object's bias. // Note that we first construct the presumed unbiased header so we // don't accidentally blow away another thread's valid bias. intptr_t unbiased = (intptr_t) mark & (markOopDesc::biased_lock_mask_in_place |

markOopDesc::age_mask_in_place |

markOopDesc::epoch_mask_in_place);

if (Atomic::cmpxchg_ptr((intptr_t)THREAD | unbiased, (intptr_t*) rcvr->mark_addr(), unbiased) != unbiased) {

CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);

}

} else {

try_rebias:

// At this point we know the epoch has expired, meaning that the // current "bias owner", if any, is actually invalid. Under these // circumstances _only_, we are allowed to use the current header's // value as the comparison value when doing the cas to acquire the // bias in the current epoch. In other words, we allow transfer of // the bias from one thread to another directly in this situation. xx = (intptr_t) rcvr->klass()->prototype_header() | (intptr_t) THREAD;

if (Atomic::cmpxchg_ptr((intptr_t)THREAD | (intptr_t) rcvr->klass()->prototype_header(),

(intptr_t*) rcvr->mark_addr(),

(intptr_t) mark) != (intptr_t) mark) {

CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);

}

}

} else {

try_revoke_bias:

// The prototype mark in the klass doesn't have the bias bit set any // more, indicating that objects of this data type are not supposed // to be biased any more. We are going to try to reset the mark of // this object to the prototype value and fall through to the // CAS-based locking scheme. Note that if our CAS fails, it means // that another thread raced us for the privilege of revoking the // bias of this particular object, so it's okay to continue in the // normal locking code. // xx = (intptr_t) rcvr->klass()->prototype_header() | (intptr_t) THREAD;

if (Atomic::cmpxchg_ptr(rcvr->klass()->prototype_header(),

(intptr_t*) rcvr->mark_addr(),

mark) == mark) {

// (*counters->revoked_lock_entry_count_addr())++; success = false;

}

}

}

} else {

cas_label:

success = false;

}

}

if (!success) {

markOop displaced = rcvr->mark()->set_unlocked();

mon->lock()->set_displaced_header(displaced);

if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) {

// Is it simple recursive case? if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {

mon->lock()->set_displaced_header(NULL);

} else {

CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);

}

}

}

}

THREAD->clr_do_not_unlock();

// Notify jvmti#ifdef VM_JVMTI if (_jvmti_interp_events) {

// Whenever JVMTI puts a thread in interp_only_mode, method // entry/exit events are sent for that thread to track stack depth. if (THREAD->is_interp_only_mode()) {

CALL_VM(InterpreterRuntime::post_method_entry(THREAD),

handle_exception);

}

}

#endif/* VM_JVMTI */

goto run;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值