2016-10-27 20 views
1

私はReentrantLockを使ってブロッキングFIFOを実装しようとしています。 IllegalMonitorStateExceptionがスローされている以外はすべて正常に動作します。 スレッドによってロックされていないリソースを解放しようとすると、このエラーが発生する可能性があります。しかし、なぜ私はこのエラーがここに来るのか分からなかった。ReentrantLockの使用中にjava.lang.IllegalMonitorStateExceptionエラーが発生しましたか?

package edu.utdallas.blockingFIFO; 

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

import edu.utdallas.taskExecutor.Task; 

public class ArrayBlockingQueue implements BlockingFIFOque{ 
    private final Task[] arr; 
    private int arrSize; 
    private int start; 
    private int end; 
    private int ocupied; 
    private final Lock mlock = new ReentrantLock(); 
    private Condition Empty = mlock.newCondition(); 
    private Condition Full = mlock.newCondition(); 

    public ArrayBlockingQueue(int Size) { 

     arrSize = Size; 
     start = 0; 
     end = 0; 
     ocupied = 0; 
     arr = new Task[arrSize]; 
    } 

    @Override 
    public void put(Task item) throws Exception { 

     mlock.tryLock(); 
     try{ 
      while(ocupied == arrSize) Full.await(); 
      ocupied++; 
      arr[end++]=item; 
      if(end > arrSize-1){ 
       end = end - arrSize; 
      } 
      Empty.signalAll(); 
     } finally{ 
      mlock.unlock(); 
     } 
    } 


    @Override 
    public Task take() throws Exception { 

     Task item; 
     mlock.tryLock(); 
     try{ 
      while(ocupied == 0) Empty.await(); 
      ocupied = ocupied - 1; 
      item = arr[start]; 
      start++; 
      if(start > arrSize-1){ 
       start = start - arrSize; 
      } 
      Full.signal(); 
     }finally{ 
      mlock.unlock(); //Error here only 
     } 

     return item; 
    } 

} 

例外

java.lang.IllegalMonitorStateException****** Adding Task SimpleTask141 
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Unknown Source) 
    at java.util.concurrent.locks.ReentrantLock.unlock(Unknown Source) 
    at edu.utdallas.blockingFIFO.ArrayBlockingQueue.take(ArrayBlockingQueue.java:61) 
    at edu.utdallas.taskExecutorImpl.TaskExecutorImpl$1.run(TaskExecutorImpl.java:38) 

答えて

3

のtryLock()は、それが意志を意味し、ブール値を返しますので

tryLock() 

しかし

lock() 

を使用しないでください可能であればロックを試みますが、ロックにb別のスレッドによってロックされていると、すぐにfalseを返します。

最後にロックを解除するときは、ロックが現在のスレッドによって保持されていないため、IllegalMonitorStateExceptionがスローされます。

+0

ありがとうございます!出来た。 – Datta

関連する問題