2013-09-20 4 views
0

У меня есть метод, как следующие в основном потоке, что вызывает метод моей структуры данных следующим образом -:Что происходит, когда метод wait вызывается внутри метода объекта?

public static void main(String[] args){ 

data_structure_object.insert(value); 
} 

и я использую ReadWrite объект называю его rwLock внутри класса структуры данных, которая используется для предотвращения помех потока, запись класса Read выглядит следующим образом -:

public class ReadWriteLocks { 

    // these 3 variables help in creating a read write lock 
    private int numberOfReaders = 0; 
    private int numberOfWriters = 0; 
    private int numberOfWriteRequests = 0; 

    // getter method for the number of readers 
    public int getNumberOfReaders() { 
     return this.numberOfReaders; 
    } 

    // getter method for the number of writers 
    public int getNumberOfWriters() { 
     return this.numberOfWriters; 
    } 

    // getter method for the number of write requests 
    public int getNumberOfWriteRequests() { 
     return this.numberOfWriteRequests; 
    } 

    // this function checks if a thread can acquire the lock 
    public synchronized void lockRead() throws InterruptedException { 

     while (numberOfWriters > 0 || numberOfWriteRequests > 0) 
      this.wait(); 
    } 

    // this function unlocks a lock occupied by a reader thread 
    public synchronized void unlockRead() { 

     // decrement the number of readers 
     --numberOfReaders; 
     notifyAll(); 
    } 

    // this function checks if a thread can acquire the write lock 
    public synchronized void lockWrite() throws InterruptedException { 

     // increase the number of write requests 
     ++numberOfWriteRequests; 

     while (numberOfReaders > 0 || numberOfWriters > 0) 
      this.wait(); 

     --numberOfWriteRequests; 
     ++numberOfWriters; 
    } 

    // this function is used to take a thread away from the lock 
    public synchronized void unlockWrite() { 

     // decrement the number of writers 
     --numberOfWriters; 

     // notify all the threads 
     this.notifyAll(); 
    } 

} 

и внутри метода вставки структуры данных, я включаю следующий фрагмент кода

// acquire the read/write lock 
     try { 
      rwLock.lockRead(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     // Some operation 

     // release the lock 
     rwLock.unlockRead(); 

Вопрос в том, является ли это действенным способом обеспечения справедливости и также блокировки потоков, чтобы поддерживать согласованность структуры данных? кроме того, я не могу понять, как я могу предоставить следующие функции: «Предоставление нескольким читателям возможности блокировки и чтения данных до тех пор, пока не будет писателя, запрашивающего или записывающего ресурс», я довольно смущен ситуация любезно поможет.

+2

Любые причины, по которым вы пытаетесь изобрести колесо? – assylias

+0

Я не пытаюсь изобретать колесо, но это что-то для моего понимания. – AnkitSablok

+1

Существует [ReadWriteLock в JDK с опцией справедливости] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html). Одна из проблем с вашим кодом (возможно, другие) заключается в том, что поток, который не имеет блокировки, может вызвать разблокировку и разрешить нескольким сценаристам работать параллельно. Также вы должны всегда вызывать разблокировку в блоке finally: если ваш код генерирует исключение, блокировка будет удерживаться навсегда. – assylias

ответ

0

Помимо того, что вы пытаетесь дублировать совершенно хороший существующий ReadWriteLock позируют как ReentrantReadWriteLock есть две определенные проблемы в вашем коде:

  1. Ваши переменные экземпляра должны быть volatile.

    private volatile int numberOfReaders = 0; 
    private volatile int numberOfWriters = 0; 
    private volatile int numberOfWriteRequests = 0; 
    
  2. Вам необходимо быть осторожным с переходом от заблокированного к заблокированному.

    --numberOfWriteRequests; 
    ++numberOfWriters; 
    

, вероятно, должен быть

++numberOfWriters; 
    --numberOfWriteRequests; 

, потому что может быть момент между этими двумя инструкциями, когда numberOfWriteRequests равен нулю и numberOfWriters равна нулю. Это позволит вашей спин-петле в lockRead, и все будет ломаться ... иногда.

Возможно, вам было бы лучше всего перевести это на проверку кода.

+0

Не уверен, что я получу второй пункт: все синхронизировано ... – assylias

Смежные вопросы