JAVA Concurrent Programming -- thread waiting wake-up mechanism and LockSupport

1. Overview of thread waiting wake-up mechanism

2. The wait and notify methods in the object class implement thread waiting and wake-up

3. The await post signal method in the condition interface realizes thread waiting and wake-up

4. Restrictions on the use of object and Condition

5. Introduction to locksupport class

6. park wait and unpark wake-up in locksupport class

7. Summary

1. Overview of thread waiting wake-up mechanism

Through the previous two Blogs:
JAVA Concurrent Programming -- the difference between Synchronized and Lock and the use of Lock
JAVA Concurrent Programming -- producer and consumer mode (traditional version & blocking queue version)

We have a preliminary understanding of the thread waiting and wake-up mechanism, and wrote several demo s to recruit one thread to wake up another thread, but these two writing methods are not very perfect. The specific imperfections and modification schemes are explained in the following blog.

2. The wait and notify methods in the object class implement thread waiting and wake-up

public class LockDemo
{
public static void main(String[] args)//Main method, main thread, all program entries
{
        Object objectLock = new Object(); //Same lock, similar to resource class

        new Thread(() -> {
           synchronized (objectLock) {
           try {
              objectLock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"\t"+"Awakened");
        },"t1").start();

           //Pause for a few seconds
           Thread.sleep(3000);

           new Thread(() -> {
               synchronized (objectLock) {
               objectLock.notify();
            }
           },"t2").start();
         }
 }

Defects:
Although the above code can make one thread wake up another thread, it has such a defect:
1) Put notify in front of the wait method, and thread t1 cannot wake up
2) The wait and notify methods must be in the synchronization block or method and used in pairs

3. The await post signal method in the condition interface realizes thread waiting and wake-up

public class LockSupportDemo2
{
public static void main(String[] args)
    {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();

        new Thread(() -> {
        lock.lock();
        try
        {
              System.out.println(Thread.currentThread().getName()+"\t"+"start");
              condition.await();
              System.out.println(Thread.currentThread().getName()+"\t"+"Awakened");
        } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
              lock.unlock();
            }
        },"t1").start();

//Pause the thread for a few seconds
        try { TimeUnit.SECONDS.sleep(3L); } catch (InterruptedException e) {         e.printStackTrace(); }

        new Thread(() -> {
        lock.lock();
        try
        {
              condition.signal();
        } catch (Exception e) {
                e.printStackTrace();
            } finally {
              lock.unlock();
            }
         System.out.println(Thread.currentThread().getName()+"\t"+"Notified");
        },"t2").start();
    }
}

Defects:
1) The await () method must precede the signal() method
2) Before the thread waiting and wake-up methods in condtion, you need to obtain the lock first

4. Restrictions on the use of object and Condition

As can be seen from the above
1) To obtain and hold a lock, a thread must be in a lock block (synchronized or lock)
2) You must wait before waking up before the thread can be awakened

5. Introduction to locksupport class

Let's first look at how the api introduces the LockSupport class:

LockSupport is the basic thread blocking primitive used to create locks and other synchronization classes

We may not understand it here. Let's continue to look at the following source code comments:

The basic meaning is:

LockSupport class uses a concept called permission to block and wake up threads. Each thread has a permission
If the park() method is called and the permission is 1, the thread will continue to execute, otherwise the thread will block immediately.

permit has only two values, 1 and zero. The default is zero. Permission can be regarded as a (0,1) Semaphore, but unlike Semaphore, the upper limit of accumulation of permission is 1.

6. park wait and unpark wake-up in locksupport class
Let's first look at the park() and unpark() methods in the document:

park() /park(Object blocker) :
Block current thread / block incoming concrete thread

unpark(Thread thread)
Wakes up the specified thread that is blocked

public class LockSupportDemo
{
public static void main(String[] args)
    {
//Normal use + no lock block required
Thread t1 = new Thread(() -> {
    System.out.println(Thread.currentThread().getName()+" "+"1111111111111");
    LockSupport.park();
    System.out.println(Thread.currentThread().getName()+" "+"2222222222222------end Awakened");
},"t1");
t1.start();

//Pause the thread for a few seconds
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }

LockSupport.unpark(t1);
System.out.println(Thread.currentThread().getName()+"   -----LockSupport.unparrk() invoked over");

}
}

advantage:
1) The wrong one wakes up first and then waits. LockSupport still supports it
2) No lock block requirements

Disadvantages:
1) Because the flag bit is 1, the thread can only wake up once. Continuous park() unpark() has no effect.

** 7. summary

Today, we mainly learned the shortcomings and improvement methods of the previous thread waiting wake-up mechanism - LockSupport. LockSupport is actually a pre knowledge for reading the future aqs source code. It well improves the defects of the previous wake-up mechanisms.

Keywords: Java Concurrent Programming JUC lock

Added by maxsslade on Sun, 26 Dec 2021 18:31:49 +0200