2017-06-18 35 views
0

我無法區分差異。我讀了這個:actual-use-of-lockinterruptibly-for-a-reentrantlocklockInterruptibly Vs鎖

並想測試它。這裏有雲代碼:

public class Test { 
public static void main(String[] args){ 
    Test test = new Test(); 
    test.inturreptWork(); 
    //Main group 
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getName()); 
    //System group is the parent of main group. it contains system level threads like finalizer,signal dispatcher,attach listener 
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getParent()); 
} 

public void inturreptWork(){ 
    Inturrept inturrept= new Inturrept(); 
    Thread t1 = new Thread(inturrept,"Thread 1"); 
    Thread t2 = new Thread(inturrept,"Thread 2"); 
    Thread t3 = new Thread(inturrept,"Thread 3"); 
    try{ 
    t1.start(); 
    Thread.sleep(1000); 
    t2.start(); 
    Thread.sleep(1000); 
    t2.interrupt(); 
    t3.start(); 
    t1.join(); 
    t2.join(); 
    t3.join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    finally { 
     System.out.println("Finally"); 
    } 


} 

這裏是Inturrept類

 public class Inturrept implements Runnable { 
    Lock lock = new ReentrantLock(); 

    @Override 
    public void run() { 
     try { 
      System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName()); 
      lock.lock();// or lock.lockInterruptibly(); 

      System.out.println("Running"); 
      Thread.sleep(7000);// Use something else to mimic sleep as it throws interrupted exception 
      lock.unlock();// This caused IllegalMonitorStateException 
     } catch (InterruptedException e) { 
      System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName()); 
      e.printStackTrace(); 
     } finally { 
      lock.unlock(); 
     } 
    } 
} 

控制檯輸出:

Trying to get lock ,Thread name is: Thread 1 
Running 
Trying to get lock ,Thread name is: Thread 2 
Trying to get lock ,Thread name is: Thread 3 
Running 
Exception in thread "Thread 1" I was inturrepted, Thread name is: Thread 2 
java.lang.IllegalMonitorStateException 
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261) 
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457) 
    at com.test.main.Inturrept.run(Inturrept.java:21) 
    at java.lang.Thread.run(Thread.java:748) 
java.lang.InterruptedException: sleep interrupted 
    at java.lang.Thread.sleep(Native Method) 
    at com.test.main.Inturrept.run(Inturrept.java:15) 
    at java.lang.Thread.run(Thread.java:748) 
Running 
Exception in thread "Thread 3" Finallyjava.lang.IllegalMonitorStateException 
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261) 
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457) 
    at com.test.main.Inturrept.run(Inturrept.java:21) 
    at java.lang.Thread.run(Thread.java:748) 

Main Thread group: main 
Main Thread group: java.lang.ThreadGroup[name=system,maxpri=10] 

正如答覆中提到:「這是一樣的定期鎖() 。但如果另一個線程中斷等待線程lockInterruptibly()將拋出InterruptedException。「 即使它是lock.lock()或lock.lockinterruptibly()。線程被中斷。所以有什麼區別?我明白了什麼錯,請協助。 還有另外一個問題我已經是爲什麼我看到線程3「在線程異常‘’在控制檯中。它跑,因爲我可以看到兩個‘在日誌的跑道’。

謝謝你。

+0

這是'sleep'拋出了'InterruptedException',不是'鎖'。當你中斷''線程'時,它會設置它的'中斷'標誌並將其留在那裏。當你的線程最終獲得鎖定時,它處於這種中斷狀態並嘗試「睡眠」。如果任何線程已經中斷了當前線程,'sleep'將拋出一個'InterruptedException'。_ –

+0

另外,請將'lock()'調用移出'try'並移除'try'塊內的'unlock()'。 –

+0

@SotiriosDelimanolis我在try中使用了lock方法,因爲我使用的是lockInterruptibly。是的,我刪除了try中的unlock,我的壞處是給出了IllegalMonitorStateException異常。另外使用thread.sleep()來檢查lockInterruptibly是否實際拋出了被中斷的異常是錯誤的。因爲當我中斷線程時,它將中斷標誌設置爲true,使得睡眠喚醒清除標誌併發送拋出的中斷異常。結果我無法確定如果lockInterruptibly實際上拋出了InterruptedException。 如果其他人來了 – Kid101

回答

0

的lockInterruptibly() )如果線程被中斷或再not.If打斷扔InterruptedException

if (Thread.interrupted()) 
      throw new InterruptedException(); 
     if (!tryAcquire(arg)) 
      doAcquireInterruptibly(arg); 

lock.unlock(第一次檢查是在你的代碼中調用兩次。所以它是扔IllegalMonitorStateException因爲不是同一個線程是做unlock.When線程做沒有鎖的解鎖就會拋出異常。

if (Thread.currentThread() != getExclusiveOwnerThread()) 
       throw new IllegalMonitorStateException(); 

的Thread.sleep引起中斷exception.Sleep方法拋出InterruptedException

void sleep(long millis) throws InterruptedException 

修改後的代碼

public void run() { 
try { 
    System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName()); 
    lock.lock(); 
    System.out.println("Running"); 
    //Thread.sleep(7000); 

} catch (Exception e) { 
    System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName()); 
    e.printStackTrace(); 
} finally { 
    lock.unlock(); 
} 

}

+0

這是由於thread.sleep –

+0

@SotiriosDelimanolis我修改了我的答案。你可以刪除倒票 –

+0

感謝您的答覆@gati我想,我應該使用除thread.sleep之外的其他東西來模仿等待。 – Kid101