Rahul Shivsharan
Rahul Shivsharan

Reputation: 2561

Tried nested locks, but still facing the deadlock

this the code in which i am trying to demonstrate nested lock problem,

  import java.util.concurrent.locks.*;


  class SharedResource{
    private static final Lock lock = new ReentrantLock();


    private void methodThree(String name,int x) throws Exception{
        lock.lock();
        while(x <= 15){
            System.out.println("METHOD-THREE / THREAD-NAME : "+name+" NUM-VAL "+x);
            x++;
            Thread.sleep(250);
        }
    }

    private void methodTwo(String name,int x) throws Exception{
        lock.lock();
        while(x <= 10){
            System.out.println("METHOD-TWO / THREAD-NAME : "+name+" NUM-VAL "+x);
            x++;
            Thread.sleep(250);
        }
        methodThree(name,x);
    }

    public void methodOne(String name,int x) throws Exception{
        try{        
            lock.lock();
            while(x <= 5){
                System.out.println("METHOD-ONE / THREAD-NAME : "+name+" NUM-VAL "+x);
                x++;
                Thread.sleep(250);
            }   
            methodTwo(name,x);          
        }finally{
            lock.unlock();
        }       
    }

  }

  class MyRequestREQ extends Thread{

    private SharedResource res;
    private int num = 1;

    MyRequestREQ(SharedResource res,String name){
        super(name);
        this.res = res;
    }

    @Override
    public void run(){      
        try{
            res.methodOne(Thread.currentThread().getName(),num);
        }catch(Exception e){
            System.out.println(e);
        }
    }
  }

  public class LockCountPractise{
    public static void main(String [] args){
        SharedResource resource = new SharedResource();
        MyRequestREQ[] requests = new MyRequestREQ[]{
            new MyRequestREQ(resource,"JACK"),
            new MyRequestREQ(resource,"JILL"),
            new MyRequestREQ(resource,"JASON")
        };

        for(int x=0; x < requests.length;x++){
            requests[x].start();
        }
    }
  }

but the output which i get is all the one run by the thread "JACK", this thread prints till count 15, and just hung up.

Is the above program face a deadlock issue ?

do i need to unlock the lock in all of the methods of class SharedResource ?

Waiting for the suggestion.

Upvotes: 3

Views: 902

Answers (2)

destan
destan

Reputation: 4411

you are not unlocking in method3 so when the first thread is done the others can't go on since they can't acquire the lock.

do i need to unlock the lock in all of the methods of class SharedResource ?

yes because every time you call lock():

If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.

see: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html#lock%28%29

as a suggestion: you can acquire the lock in method1 and release it in method3. so there will be 1 lock 1 unlock, you'll be fine. no need to 3 lock-unlock cycle.

actually it depends what behaviour you want:

  • To let different threads acquire the lock between counters (thread1 counts to 5 then thread3 comes and counts then thread1 continues) you need lock-unlock in every method.
  • To get one thread start and finish counting without any interfere you need 1 lock-unlock

Upvotes: 3

Andreas Dolk
Andreas Dolk

Reputation: 114807

Jack is locking the Lock three times but releasing only once. lock() is counting:

lock()

If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.

unlock()

If the current thread is the holder of this lock then the hold count is decremented. If the hold count is now zero then the lock is released.

(JavaDoc)

Upvotes: 0

Related Questions