尝试嵌套锁,但仍面临死锁

时间:2012-02-08 07:20:50

标签: java multithreading thread-safety

这是我试图演示嵌套锁定问题的代码,

  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 个答案:

答案 0 :(得分:3)

你没有在方法3中解锁,所以当第一个线程完成时,其他人不能继续,因为他们无法获得锁定。

  

我是否需要解锁所有类的方法中的锁   SharedResource?

是的,因为每次拨打lock()

  

如果当前线程已经保持锁定,则保持计数为   增加1,方法立即返回。

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

作为建议:您可以获取method1中的锁并在method3中释放它。所以将有1个锁1解锁,你会没事的。无需3次锁定解锁循环。

实际上它取决于你想要的行为:

  • 为了让不同的线程获得计数器之间的锁定(thread1计数到5然后thread3到来并计数然后thread1继续)你需要在每个方法中锁定解锁。
  • 要让一个线程开始并完成计数而没有任何干扰,您需要1个锁定解锁

答案 1 :(得分:0)

杰克锁定锁定三次但只释放一次。 lock()正在计算:

<强>锁()

  

如果当前线程已经保持锁定,则保持计数加1,方法立即返回。

<强>解锁()

  

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

(JavaDoc的)