尝试过使用嵌套锁,但仍然面临僵局

问题描述:

这其中我试图证明嵌套锁问题的代码,尝试过使用嵌套锁,但仍然面临僵局

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的所有方法中的锁?

等待建议。

你没有在method3中解锁,所以当第一个线程完成后,其他人无法继续,因为他们无法获得锁。

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

是因为每次你打电话lock()时间:

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

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

的建议:你可以获取方法1锁和方法3松开。所以会有1锁1解锁,你会没事的。无需3次锁定 - 解锁循环。

实际上这取决于你想要什么样的行为:

  • 为了让不同的线程获取计数器之间的锁(线程1数到5,然后thread3来得快,计数然后线程1继续),你需要锁定解锁的每一个方法。
  • 为了得到一个线程开始和结束计数没有任何干扰,你需要1个锁定解锁
+0

感谢您的答复,我可以锁定解锁在第一方法本身,从方法2和3中除去所有的锁,这是一个正确的方法? – 2012-02-08 07:37:45

+0

正确的方法取决于你想要的。正如在我编辑答案1锁定解锁使得线程依次计数 – destan 2012-02-08 07:42:00

+0

并且还注意到,当您使用1锁定解锁时,对于这种特定情况,在method1或method3中的解锁将是相同的。 – destan 2012-02-08 07:43:09

杰克锁定锁定3次,但仅释放一次。 lock()计数:

锁()

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

解锁()

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

(JavaDoc的)