Why the lock must be acquired before Object.wait ()/notify ()/notifyall (). This is JLS's rule. Wait-notify mechanism is around the monitor lock, the acquisition of a lock is a natural prerequisite, not to get the lock, how can try to operate by locking to regulate the thread it. But today, occasionally, there is time to see how the sun hotspot to achieve this mechanism.
When we execute the following code, the thread throws an exception java.lang.IllegalMonitorStateException:current thread not owner.
Public class Waitnotifycompilercode {privateString astring = "Hello world!";
Public Static void Main (string[] args) {System.out.println ("Execute start ..."); Final Waitnotifycompilercode w =new waitnotifycompilercode ();
W.wait1secandprintstring (); System.out.println ("Execute end ...");}
Public void wait1secandprintstring () {try{this. Wait (1000);} Catch (Interruptedexception e) {
e.printstacktrace ();} System.out.println (astring);}
}
The information for the exception stack is as follows:
Exception in thread ' main ' java.lang.IllegalMonitorStateException:current thread not owner at
Java.lang.Object.wait (Nativemethod) at
Com.feihoo.test.waitnotify.WaitNotifyCompilerCode.wait1SecAndPrintString (waitnotifycompilercode.java:35)
At Com.feihoo.test.waitnotify.WaitNotifyCompilerCode.main (waitnotifycompilercode.java:27)
Dig into the OPENJDK source and find the object.wait () function Local code:
Jvm_entry (void, jvm_monitorwait (jnienv* env, jobject handle, Jlong ms))
jvmwrapper ("jvm_monitorwait");
Handle obj (THREAD, Jnihandles::resolve_non_null (Handle)), Assert (Obj->is_instance () | | Obj->is_array (), "jvm_ Monitorwait must apply to an object ");
Javathreadinobjectwaitstate jtiows (thread, Ms!=0); if (jvmtiexport::should_post_monitor_wait ()) {
Jvmtiexport:: Post_monitor_wait ((Javathread *) THREAD, (OOP) obj (), MS);
Objectsynchronizer::wait (obj, MS, CHECK);
Jvm_end
Focus on the penultimate line, called functions like the following code:
Note:must use heavy weight monitor to handle wait () void objectsynchronizer::wait (handle obj, Jlong Millis, traps) {if (U sebiasedlocking) {
Biasedlocking::revoke_and_rebias (obj, false, THREAD); assert (!obj->mark ()->has_bias_ Pattern (), "biases should is revoked by now");} if (Millis <0) {
tevent (Wait-throw iax);
Throw_msg (Vmsymbols::java_lang_illegalargumentexception (), "timeout value is negative");}
objectmonitor* monitor = Objectsynchronizer::inflate (THREAD, obj ());
Dtrace_monitor_wait_probe (MONITOR, obj (), THREAD, Millis);
Monitor->wait (Millis, True, THREAD);
In the last line of the code, the following macro was called before the actual operation was done:
A macro is used below because there could already be a pending//exception the which
utines//which use this (which is why we don ' t "put" to check_slow and//call it with a check argument). #define Check_owner () \ Do { \ if (THREAD!= _owner) { \ if (thread->is_lock_owned (address) _owner) {\ _owner = THR EAD; * Convert from Basiclock addr to Thread addr * * _recursions = 0; \ owneristhread = 1; } else {\ tevent (Throw imsx);
\ THROW (Vmsymbols::java_lang_illegalmonitorstateexception ()); \
} \
} \} while (false)