javamultithreadingsynchronizationreentrantlock

How is unlock happening after await


I wrote a small program to print odd-even numbers alternatively but have a question:

Since thread should wait at await call so how is reentrant lock is getting unlocked?

public class Worker implements Runnable
{
    private ReentrantLock rLock = null;
    private Condition condition = null;
    private String name;
    volatile static boolean isEvenTurn = true;
    
    public Worker(String name, ReentrantLock rLock, Condition condition)
    {
        this.name = name;
        this.rLock = rLock;
        this.condition = condition;
    }
    
    @Override
    public void run() 
    {
        try
        {
            if(name.equals("ODD"))
                printOdd();
            else
                printEven();
        }
        catch(Exception e) { e.printStackTrace();}
        
    }
    
    private void printOdd() throws Exception
    {
        while(isEvenTurn);
        for(int i=1;i<10;i+=2)
        {
            try
            {
                rLock.lock();
                System.out.println(i);
            }
            catch(Exception e) {e.printStackTrace();}
            finally
            {
                condition.signal();
                condition.await();
                rLock.unlock();
            }
        }
    }
    
    private void printEven() throws Exception
    {
        for(int i=0;i<10;i+=2)
        {
            try
            {
                rLock.lock();
                System.out.println(i);
                isEvenTurn = false;
            }
            catch(Exception e) {e.printStackTrace();}
            finally
            {
                condition.signal();
                condition.await();
                rLock.unlock();
            }
        }
    }
    
    public static void main(String[] args) 
    {
        ReentrantLock rLock = new ReentrantLock();
        ExecutorService service = Executors.newFixedThreadPool(2);
        
        Condition c = rLock.newCondition();
        Worker oddPrinter = new Worker("ODD",rLock,c);
        Worker evenPrinter = new Worker("EVEN",rLock,c);
        
        service.execute(evenPrinter);
        service.execute(oddPrinter);
        
        service.shutdown();
    }
}

Solution

  • In printEven() method add this line: in finally block:

           finally
            {
                condition.signal();
                if(i < 10)condition.await(); 
                rLock.unlock();
            }
    

    By adding this condition, when your i = 10 your thread will not wait anymore.