The Lock with the Condition

Lock and Condition were introduced in Java in 1.5,

Lock deals with synchronization, Condition deals with collaboration,

Lock synchronized Condition wait()/nofity()

Differences between Lock/Condition and synchronized/wait/notify

Synchronized can do things that Lock can’t

  1. Synchronized lock There is only one condition for obtaining a lock, that is, lock competition for the same object resource. It is impossible to expand some conditions to determine whether a lock can be obtained.

  2. Synchronized has no way to achieve read and write separation. When multiple threads acquire a resource, only one thread may write, while others just want to read. However, synchronized does not care whether it is read or write, as long as multiple threads access the same resource, they must serialize wait.

  3. Synchronized cannot judge whether a lock is occupied or not. For example, when a thread tries to acquire a resource, if the resource is occupied, the thread will do other things; if it is not occupied, it will acquire the resource. Synchronized can only set a lock to wait when a thread tries to acquire the occupied resource.

  4. Synchronized cannot achieve a fair lock, and when preempting the lock, it is likely that the later thread gets the lock before the first thread, which may cause some threads to wait all the time, commonly known as thread hunger.

  5. Synchronized cannot release the current lock through conditional judgment in a lock method and can only wait for the complete execution of the current method.

What lock cannot do

Synchronized can automatically release the Lock after the method is executed or an exception is thrown, while Lock needs to be unlocked manually. Especially, the unlocking operation must be placed in finally for safety. Note that Lock and unlock must occur in pairs; otherwise, the Lock cannot be released and other threads cannot obtain the Lock.

public synchronized static void syncHello() { System.out.println("hello"); } public static void lockHello() { lock.lock(); try { System.out.println("hello"); } finally { lock.unlock(); }}Copy the code

You can do both

Both can do reentrant locking.

One of the features of synchronized is reentrant locking, which means that when a thread holds a lock,

When you encounter the lock again, you can continue to enter the lock. It is not impossible to enter the lock again because the lock resource has been held by yourself. This is in line with conventional thinking logic, because the thing itself is in my own hands, I can of course use it all the time.

Synchronized implements reentrant locking:

    public static void main(String[] args) {
        a();
        b();
    }

    public synchronized static void a() {
        System.out.println("a");
    }
    
    public synchronized static void b() {
        System.out.println("b");
    }
Copy the code

ReentrantLock: ReentrantLock: ReentrantLock: ReentrantLock: ReentrantLock: ReentrantLock: ReentrantLock: ReentrantLock: ReentrantLock

ReentrantLock is one of the subclasses of Lock, which is translated into Chinese as ReentrantLock. In daily use, ReentrantLock is most commonly used, so it is the most frequently used class.

    static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        a();
        b();
    }

    public static void a() {
        lock.lock();
        System.out.println("a");
        lock.unlock();
    }

    public static void b() {
        lock.lock();
        System.out.println("b");
        lock.unlock();
    }

Copy the code

Condition

Lock is used for thread locking and unlocking, while Condition is used for thread coordination, such as when to wait and when to wake up. The common methods are as follows:

  1. await, the current thread enters the wait state and cedes the lock to someone else
  2. signalTo inform aawaitThe thread can continue executing
  3. signalAll, notify all in the currentlockIn the lockawaitThe thread can execute, but multiple threads that have been awakened must try again to acquire the lock(after waking up multiple threads, only one thread can obtain the lock to continue executing the following code to ensure thread safety)

The main purpose of using this class is to determine when a thread should stop and start doing things. Let’s use lock and condition to implement a producer + consumer model.