Search code examples
javamultithreadingooplockingreentrantlock

Java : ReentrantLock doesn't work It still mixing with each other


I can't figure out why the code doesn't work properly. The threads still mixing with each other.

I have class A :

package com.company;

public class A implements Runnable {
    ReentrantLockClass r;

    public A(ReentrantLockClass r) {
        this.r = r;
    }

    @Override
    public void run() {
        r.print(5);
    }
}

and class B :

package com.company;

public class B implements Runnable{
    ReentrantLockClass r;

    public B(ReentrantLockClass r) {
        this.r = r;
    }

    @Override
    public void run() {
        r.print(10);
    }
}

and this is ReentrantLockClass for run ReentrantLock

package com.company;

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockClass {
    public void print(int count){
        ReentrantLock lock = new ReentrantLock();
        try {
            lock.lock();
            for(int i = 1 ; i <= 10 ; i ++){
                System.out.println(count * i);
                Thread.sleep(500);
            }
        }
        catch (Exception e){}
        finally {
           lock.unlock();
        }
    }
}

this is the main class:

package com.company;

public class Main {

    public static void main(String[] args) {
        ReentrantLockClass r = new ReentrantLockClass();

        A a = new A(r);
        B b = new B(r);

        Thread t1 = new Thread(a);
        Thread t2 = new Thread(b);

        t1.start();
        t2.start();
    }
}

this is the output : enter image description here

It should run one thread then run the others


Solution

  • The print method creates a new ReentrantLock instance. Thus, each thread locks its own lock, so they do not block each other. One approach is to create the lock in the ReentrantLockClass' (implicit) constructor , and then lock it in the print method:

    public class ReentrantLockClass {
        // One lock shared for the instance
        ReentrantLock lock = new ReentrantLock();
    
        public void print(int count){
            try {
                lock.lock();
                for(int i = 1 ; i <= 10 ; i ++){
                    System.out.println(count * i);
                    Thread.sleep(500);
                }
            }
            catch (Exception e){}
            finally {
               lock.unlock();
            }
        }
    }