Core Java says:

A lock object can have one or more associated condition objects.

For example, create three child threads on the main thread. Each thread is responsible for one operation, but only after the first operation is completed can the second operation start. Leetcode has a similar problem. This example can be implemented in two ways, using Lock and Condition and synchronized. The code doesn’t feel much different either way.

Lock & Condition

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class ShareResource {
    private int num = 1;
    private Lock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();
 
    public void print5(a) {
        lock.lock();
        try {
            while(num ! =1) {
                conditionA.await();
            }
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
            }
            num = 2;
            conditionB.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally{ lock.unlock(); }}public void print10(a) {
        lock.lock();
        try {
            while(num ! =2) {
                conditionB.await();
            }
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
            }
            num = 3;
            conditionC.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally{ lock.unlock(); }}public void print15(a) {
        lock.lock();
        try {
            while(num ! =3) {
                conditionC.await();
            }

            for (int i = 0; i < 15; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
            }

            num = 1;
            conditionA.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally{ lock.unlock(); }}}public class LockCondition {
    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        
        new Thread(() -> {
        	shareResource.print5();
        }, "A Thread").start();
 
        new Thread(() -> {
        	shareResource.print10();
        }, "B Thread").start();
 
        new Thread(() -> {
        	shareResource.print15();
        }, "C Thread").start(); }}Copy the code

synchronized

class ShareResource {
    
    private int num = 1;
     
    // Synchronized can also be removed and placed in front of void
    public void print5(a) {
        synchronized(this) {
            try {
                while(num ! =1) wait(); 
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
                }
                num = 2; 
                notifyAll();
            } catch(InterruptedException e) { e.printStackTrace(); }}}public void print10(a) {
        synchronized(this) {
            try {
                while(num ! =2) wait(); 
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
                }
                num = 3; 
                notifyAll(); 
            } catch(InterruptedException e) { e.printStackTrace(); }}}public void print15(a) {
        synchronized(this) {
            try {
                while(num ! =3) wait(); 
                for (int i = 0; i < 15; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t" + (i+1));
                }
                num = 1;
                notifyAll(); 
            } catch(InterruptedException e) { e.printStackTrace(); }}}}public class LockCondition {
    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        
        new Thread(() -> {
        	shareResource.print5();
        	}, "A Thread").start();
 
        new Thread(() -> {
        	shareResource.print10();
        }, "B Thread").start();
 
        new Thread(() -> {
        	shareResource.print15();
        }, "C Thread").start(); }}Copy the code