2017-06-18 44 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