The relationship between synchronized, wait, and notify in JAVA Multithreading

Source: Internet
Author: User

Synchronized is associated with a lock object. When synchronized limits the static method,
The lock object is the class variable of this class, which is equivalent to XXXClass. class.
When synchronized limits non-static methods, the lock object is an instance of this class (equivalent to this ).
When synchronized limits an object instance, for example (synchronized (xlock), the lock object is the specified object instance, such as xlock.
Only the thread that obtains the lock object can execute the code restricted by synchronized.
When synchronized limits the static method, at a certain time point, only one thread in the same virtual machine can execute this static method,
Because the lock object is the XXXClass. class instance of this class, a VM has only one XXXClass. class instance.
When synchronized restricts non-static methods of a class,
At a certain time point, only one thread in the same virtual machine can execute this method, but the specific method of multiple instances can be executed at the same time, because the Lock Object is different.
Wait, policy, and policyall can only be called on one lock object; otherwise, the following exception occurs:
Java. lang. IllegalMonitorStateException: current thread not owner
The following code is valid: the first example calls this. policyall (); this is the lock object.
[Java]
Public synchronized void sendNotification () throws Exception {
Policyall ();
}
 
Synchronized (policywaittest. lock ){
Try {
Policywaittest. lock. policyall ();
} Catch (Exception e ){
E. printStackTrace ();
}
}

Public synchronized void sendNotification () throws Exception {
Policyall ();
}

Synchronized (policywaittest. lock ){
Try {
Policywaittest. lock. policyall ();
} Catch (Exception e ){
E. printStackTrace ();
}
} Void Policy ()
Wake up a thread waiting on this object monitor. Which one can be considered uncertain.
Void policyall ()
Wake up all threads waiting on this object monitor.
Void wait ()
This causes the current thread to wait until other threads call the notify () method or the notifyAll () method of this object.
Wait releases the occupied lock, and policy and policyall do not release the occupied lock.
The following is an example code:
[Java]
Public class policywaittest {
Public static Class lock = policywaittest. class;
 
Public static void main (String [] args) throws Exception {
// New TestThread1 (). start ();
// New TestThread1 (). start ();
New TestThread2 (). start ();
New TestThread2 (). start ();
 
Thread. sleep (3000 );
// Policywaittest. lock. policyall (); // # poing 1
Synchronized (policywaittest. lock ){
Try {
System. out. println (Thread. currentThread (). getName () + "sent notification all ");
Policywaittest. lock. policyall ();
 
// System. out. println (Thread. currentThread (). getName () + "sent notification 1 ");
// Policywaittest. lock. Policy ();
// System. out. println (Thread. currentThread (). getName () + "sent notification 2 ");
// Thread. sleep (3000 );
// Policywaittest. lock. Policy ();
// System. out. println (Thread. currentThread (). getName () + "sent notification over ");
 
} Catch (Exception e ){
E. printStackTrace ();
}
}
}
 
}
 
Class TestThread1 extends Thread {
Public void run (){
Synchronized (policywaittest. lock ){
Try {
System. out. println (Thread. currentThread (). getName () + "wait for notification ");
Policywaittest. lock. wait ();
 
System. out. println (Thread. currentThread (). getName () + "wake up ");
For (int I = 0; I <3; I ++ ){
Thread. sleep (1000 );
System. out. println (Thread. currentThread (). getName () + "doing" + I );
}
} Catch (Exception e ){
E. printStackTrace ();
}
System. out. println (Thread. currentThread (). getName () + "finished ");
}
}
}
 
Class TestThread2 extends Thread {
 
Public void run (){
Synchronized (policywaittest. lock ){
System. out. println (Thread. currentThread (). getName () + "wait for notification ");
Try {
Policywaittest. lock. wait ();
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
System. out. println (Thread. currentThread (). getName () + "wake up ");
For (int I = 0; I <3; I ++ ){
Try {
Thread. sleep (1000 );
} Catch (InterruptedException e ){
E. printStackTrace ();
}
System. out. println (Thread. currentThread (). getName () + "doing" + I );
}
}
}

Public class policywaittest {
Public static Class lock = policywaittest. class;

Public static void main (String [] args) throws Exception {
// New TestThread1 (). start ();
// New TestThread1 (). start ();
New TestThread2 (). start ();
New TestThread2 (). start ();

Thread. sleep (3000 );
// Policywaittest. lock. policyall (); // # poing 1
Synchronized (policywaittest. lock ){
Try {
System. out. println (Thread. currentThread (). getName () + "sent notification all ");
Policywaittest. lock. policyall ();

// System. out. println (Thread. currentThread (). getName () + "sent notification 1 ");
// Policywaittest. lock. Policy ();
// System. out. println (Thread. currentThread (). getName () + "sent notification 2 ");
// Thread. sleep (3000 );
// Policywaittest. lock. Policy ();
// System. out. println (Thread. currentThread (). getName () + "sent notification over ");

} Catch (Exception e ){
E. printStackTrace ();
}
}
}

}

Class TestThread1 extends Thread {
Public void run (){
Synchronized (policywaittest. lock ){
Try {
System. out. println (Thread. currentThread (). getName () + "wait for notification ");
Policywaittest. lock. wait ();

System. out. println (Thread. currentThread (). getName () + "wake up ");
For (int I = 0; I <3; I ++ ){
Thread. sleep (1000 );
System. out. println (Thread. currentThread (). getName () + "doing" + I );
}
} Catch (Exception e ){
E. printStackTrace ();
}
System. out. println (Thread. currentThread (). getName () + "finished ");
}
}
}

Class TestThread2 extends Thread {

Public void run (){
Synchronized (policywaittest. lock ){
System. out. println (Thread. currentThread (). getName () + "wait for notification ");
Try {
Policywaittest. lock. wait ();
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
System. out. println (Thread. currentThread (). getName () + "wake up ");
For (int I = 0; I <3; I ++ ){
Try {
Thread. sleep (1000 );
} Catch (InterruptedException e ){
E. printStackTrace ();
}
System. out. println (Thread. currentThread (). getName () + "doing" + I );
}
}
} Start two subthreads in the main thread. The main thread and the two threads use the same lock object. The subthread enters
Wait, the main thread uses yyall to wake up two subthreads.
The running result is:
[Java]
Thread-0 wait for notification
Thread-1 wait for notification
Main sent notification all
Thread-0 wake up
Thread-0 doing 0
Thread-0 doing 1
Thread-0 doing 2
Thread-0 finished
Thread-1 wake up
Thread-1 doing 0
Thread-1 doing 1
Thread-1 doing 2
Thread-1 finished

Thread-0 wait for notification
Thread-1 wait for notification
Main sent notification all
Thread-0 wake up
Thread-0 doing 0
Thread-0 doing 1
Thread-0 doing 2
Thread-0 finished
Thread-1 wake up
Thread-1 doing 0
Thread-1 doing 1
Thread-1 doing 2
Thread-1 finished * 1. If you do not call policy, policyall, or wait for the lock object associated with synchronized, an exception occurs.
// NotifyWaitTest. lock. policyall (); // # An exception occurred in point 1.
* 2. policyall will wake up all the waiting threads on the lock object.
* 3. In the run method of TestThread1, the code after wait is synchronized, and the two threads that wake up are executed after one is completed before the other is executed.
* 4. If notify is used in the main method, the two subthreads after "sent notification over" Will
When wait is paused, it continues to be executed because notify does not release the lock. At this time, main also occupies the lock of the policywaittest. lock Object.
[Java]
System. out. println (Thread. currentThread (). getName () + "sent notification 1 ");
Policywaittest. lock. Policy ();
System. out. println (Thread. currentThread (). getName () + "sent notification 2 ");
Thread. sleep (3000 );
Policywaittest. lock. Policy ();
System. out. println (Thread. currentThread (). getName () + "sent notification over ");
The running result is
Thread-0 wait for notification
Thread-1 wait for notification
Main sent notification 1
Main sent notification 2
Main sent notification over
Thread-0 wake up
Thread-0 doing 0
Thread-0 doing 1
Thread-0 doing 2
Thread-0 finished
Thread-1 wake up
Thread-1 doing 0
Thread-1 doing 1
Thread-1 doing 2
Thread-1 finished

System. out. println (Thread. currentThread (). getName () + "sent notification 1 ");
Policywaittest. lock. Policy ();
System. out. println (Thread. currentThread (). getName () + "sent notification 2 ");
Thread. sleep (3000 );
Policywaittest. lock. Policy ();
System. out. println (Thread. currentThread (). getName () + "sent notification over ");
The running result is
Thread-0 wait for notification
Thread-1 wait for notification
Main sent notification 1
Main sent notification 2
Main sent notification over
Thread-0 wake up
Thread-0 doing 0
Thread-0 doing 1
Thread-0 doing 2
Thread-0 finished
Thread-1 wake up
Thread-1 doing 0
Thread-1 doing 1
Thread-1 doing 2
Thread-1 finished if TestThread2 is started in the main method, because
The code is not synchronized, so it can be executed in parallel after wakeup.
[Java] www.2cto.com
New TestThread2 (). start ();
New TestThread2 (). start ();
The running result is:
Thread-0 wait for notification
Thread-1 wait for notification
Main sent notification all
Thread-0 wake up
Thread-1 wake up
Thread-0 doing 0
Thread-1 doing 0
Thread-0 doing 1
Thread-1 doing 1
Thread-0 doing 2
Thread-1 doing 2


Author: kkdelta

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.