The wait () process
  1. Wrap the current thread as a Wait_node object
  2. Add the wait_node object to the wait_set queue
  3. Use the park() function to suspend the thread and release the lock
Other threads compete for the lock process(Note that the word “lock” refers to synchronize)
  1. Check the lock status. If there is no lock, use the CAS to compete for the lock
  2. Returns if it is locked and if the thread is the owner of the lock
  3. Triggers the lock inflation mechanism if the owner of the lock is not owned by the thread
    • The for loop is first entered to see if the lock is already in a heavyweight state, and if so, it returns directly
    • If the lock stateinflating(expanding) and wait for a while
    • If the status of the lock is lightweight, use the CAS primitive to set its state toinflating
    • The header, owner, and other fields of the objectMoniter are updated and return the objectMoniter on success
  4. Continue competing for locks after successful expansion
  5. If the race fails, wrap the thread as a Wait_node object and place it on the ** _CXq ** queue
  6. An infinite loop in the ** _CXq ** queue races for the lock again, breaking the loop if the race succeeds, and park() suspends the thread if the race fails
Notify () process
  1. Start by selecting a thread that has been placed on the wait_set queue using wait()
  2. Put the thread into the EntryList or _CXQ queue, depending on the policyThe notify() method does not wake up any threads, because the current thread may not have completed its task, but simply selected a random thread and placed it on the queue
The exit () process

The thread enters this method when it has completed its task, and this method is the key to releasing the lock and waking up other threads

  1. Release the lock
  2. Wake up a thread from the EntryList or _CXQ queue to compete for the lock

Why must wait()/notify() be inside the synchronization block?

Each object has its own monitor lock. When a thread uses wait(), it must own the lock. If it does not own a monitor in a synchronized block, the same applies to notify(). For example, in the producer-consumer model, if the consumer does not use synchronize and other synchronization methods, wait() is executed after notify() when the consumer finds that the number of products is insufficient and the CPU resources are insufficient. The consumer uses wait() to wait for the product.

Briefly describe the differences between yield(),sleep(),wait(), and join() functions

The sleep() function frees CPU resources by putting the current thread to sleep. The thread does not release its own lock, but only frees CPU resources for other threads that do not need to change the lock object. The sleep() function sets the sleep time.

The yield() function is similar to the sleep() function, except that it takes no input arguments. The yield() function also frees CPU resources, but it only lets other threads with the same priority run. It first looks for threads with the same priority and frees CPU resources if it finds one.

The join() function cedes CPU resources to the caller of the method and the current thread goes to sleep.

(It is only used to record personal experience in daily learning. Please kindly advise if there is any mistake.)