尝试使用嵌套锁,但仍然面临死锁问题。

3
这是我试图演示嵌套锁问题的代码:
  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();
        }
    }
  }

但是我得到的输出都是由名为“JACK”的线程运行的,这个线程打印了直到计数15,然后就一直停住了。
上面的程序是否面临死锁问题?
我需要在SharedResource类的所有方法中解锁吗?
期待您的建议。
2个回答

3

你没有在方法3中解锁,所以当第一个线程完成时,其他线程无法继续执行,因为它们无法获取锁。

我需要在类SharedResource的所有方法中解锁吗?

是的,因为每次调用lock()时:

如果当前线程已经持有该锁,则保持计数增加1并立即返回。

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

建议:您可以在方法1中获取锁,在方法3中释放锁。这样就只有1个锁定和1个解锁,就可以了,不需要进行三次锁定-解锁过程。

实际上,它取决于您想要什么行为:

  • 让不同的线程在计数器之间获取锁(线程1计数到5,然后线程3开始计数,然后线程1继续),您需要在每种方法中进行锁定-解锁。
  • 要使一个线程开始和结束计数而没有任何干扰,您需要1次锁定-解锁

谢谢回复,我能否在第一种方法中锁定并解锁,从而删除第二种和第三种方法中的所有锁定,这是正确的方法吗? - Rahul Shivsharan
正确的方法取决于你想要什么。就像我编辑后的答案所示,使用锁定-解锁可以使线程依次计数。 - destan
请注意,当您使用1个锁定-解锁时,在这种特殊情况下,在method1或method3中解锁将是相同的。 - destan

0

Jack将锁定锁三次,但仅释放一次。lock()在计数:

lock()

如果当前线程已经持有该锁,则持有计数将增加1,并且该方法立即返回。

unlock()

如果当前线程是此锁的持有者,则将持有计数递减。如果现在的保持计数为零,则释放该锁。

(JavaDoc)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接