7 Replies Latest reply: Oct 14, 2012 2:32 PM by EJP RSS

    Readers Writers problem and Synchronized doubts

    968204
      I made this code for implementing some Lock because I have to permit the write/read action on shared file between different threads. I would like to let more than one thread reading at the same time and just one for the writing

      This is my code, it's in italian but in english the class name would be AccessManager

      import java.io.Serializable;
      public class GestoreAccessi implements Serializable{
      //number of reader
      private int lettori= 0;
      //flag for someone writing
      private boolean scrittura= false;
      //number of writer waiting
      private int scrittoriAttesa = 0;
      private String nome;

      //Il gestore accessi prende un nome
      public GestoreAccessi(String nom) {
      nome = nom;
      }
      //Blocco per la lettura -- Lock for Reading
      public synchronized void lockRead() {
      try {
      //Fino a che c'e' qualcuno in scrittura o processi che aspettano per la scrittura mi metto in attesa -- If ther is some thread writing or waiting for write
      while (scrittura || scrittoriAttesa > 0) {
      wait();
      }
      //Altrimenti aumento la variabile dei thread in lettura -- Add one thread reading
      ++lettori;
      } catch (InterruptedException ex) {
      }
      }
      //Fine del processo di lettura -- Finish reading
      public synchronized void unlockRead() {
      --lettori;
      // solo gli scrittori sono in attesa e uno soltanto deve essere svegliato
      if (lettori == 0) {
      notifyAll();
      }
      }
      //Blocco per la scrittura -- Start Writing
      public synchronized void lockWrite() {
      ++scrittoriAttesa;
      //Fino a che ci sono lettori o qualcuno che scrive aspetto -- if there are readers o someone writing
      while (lettori > 0 || scrittura) {
      try {
      wait();
      } catch (InterruptedException ex) {
      }
      }
      --scrittoriAttesa;
      //Altrimenti inizio il processo di lettura -- Start the process of reading
      scrittura = true;
      }
      //Fine del processo di scrittura
      public synchronized void unlockWrite() {
      scrittura = false;
      notifyAll(); // sblocca uno o piu' lettori o uno scrittore
      }
      }

      Before all critical part I create a GestoreAccessi object and invoce the .lock.. method and finish the critical part the .unlock.. Do you think it's a good way to solve the problem?

      I have some doubts on the multiple reading at the same time. I read on synchronized: "First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
      Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads."

      It's possible to two different thread read at the same time? The .lockRead() method is synchronized: if one thread has acess in a critical part it takes the lock and no other thread would be able to have an access on the same part?! How can i do this? I have not to declare synchronized the read method?

      Please help me and sorry for my bad english!!
      Bless from Italy
        • 1. Re: Readers Writers problem and Synchronized doubts
          EJP
          I would like to let more than one thread reading at the same time and just one for the writing
          Then you need to use java.util.concurrent.locks.ReadWriteLock.
          • 2. Re: Readers Writers problem and Synchronized doubts
            968204
            I understood right than, my solution is not working right (and at last doesn't let more than one thread reading) because the method "lockRead" is synchronized and just one thread can execute the critic part of code protected by the lock? Does the synchronized declaration work in this way??

            i'm just watching the ReadWriteLock interface and this what I was trying to do but i haven't understood how can you notify the releasing of the lock and how the interface can create the mutual exclusion only for writing. Can I adapt my code for implemnting the ReadWriteLock? It doesn't need any synchronized method?
            • 3. Re: Readers Writers problem and Synchronized doubts
              EJP
              Throw your code away and use the class provided.
              • 4. Re: Readers Writers problem and Synchronized doubts
                968204
                Can you tell me if I have understood right the mecanism of synchronization?
                me wrote:
                I understood right than, my solution is not working right (and at last doesn't let more than one thread reading) because the method "lockRead" is synchronized and just one thread can execute the critic part of code protected by the lock? Does the synchronized declaration work in this way??.
                I would like to undeasteand it..



                For working right I wold have done something like this?

                ReadWriteLock lock = new ReentrantReadWriteLock();
                lock.readLock().lock();
                // multiple readers allow in this section??
                lock.readLock().unlock();

                lock.writeLock().lock();
                // only one writer can enter this section??
                lock.writeLock().unlock();
                • 5. Re: Readers Writers problem and Synchronized doubts
                  rp0428
                  >
                  I made this code for implementing some Lock because I have to permit the write/read action on shared file between different threads. I would like to let more than one thread reading at the same time and just one for the writing
                  >
                  Multiple threads and even applications can read the same file at the same time; it is writing that is problematic.

                  There is nothing in what you posted that even shows any 'file' manipulation so no comments can be made about that.

                  It looks like you took those quotes from this Java Tutorial Page on Synchronizeds Methods
                  http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

                  Those quotes are accurate as far as synchronizing a particular instance is concerned but that would not prevent some other code from trying to read/write the same file. But again, you code doesn't even include any file-related objects that you are trying to control access to.

                  See the Java Tutorial section on 'Lock Objects'
                  http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html
                  • 6. Re: Readers Writers problem and Synchronized doubts
                    rp0428
                    >
                    me wrote:
                    I understood right than, my solution is not working right (and at last doesn't let more than one thread reading) because the method "lockRead" is synchronized and just one thread can execute the critic part of code protected by the lock? Does the synchronized declaration work in this way??.

                    I would like to undeasteand it..
                    >
                    The above is correct as the doc quote you cited states.

                    However, as EJP already said that isn't going to be of use in solving your problem.
                    • 7. Re: Readers Writers problem and Synchronized doubts
                      EJP
                      ReadWriteLock lock = new ReentrantReadWriteLock();
                      lock.readLock().lock();
                      // multiple readers allow in this section??
                      lock.readLock().unlock();

                      lock.writeLock().lock();
                      // only one writer can enter this section??
                      lock.writeLock().unlock();
                      Isn't that exactly what the Javadoc says?