[concurrency-interest] Is it possible to prevent out of orderexecution by using reader writer lock?

David Holmes davidcholmes at aapt.net.au
Thu Feb 3 16:41:11 EST 2011


I don't seem to have received the original email on this and can't quite
extract what the original question was, but from the subject I think the
question is just about the happens-before ordering provided by a
ReadWriteLock.

All ReadWriteLock implementations must guarantee that the memory
synchronization effects of writeLock operations (as specified in the Lock
interface) also hold with respect to the associated readLock. That is, a
thread successfully acquiring the read lock will see all updates made upon
previous release of the write lock.

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/Read
WriteLock.html

David Holmes
  -----Original Message-----
  From: concurrency-interest-bounces at cs.oswego.edu
[mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Yan Cheng
CHEOK
  Sent: Friday, 4 February 2011 5:29 AM
  To: Bob Hiestand
  Cc: concurrency-interest at cs.oswego.edu
  Subject: Re: [concurrency-interest] Is it possible to prevent out of
orderexecution by using reader writer lock?


              Hi Bob,


              Take note that, the reference of the object is being stored in
a local variable. After assignment to local variable, any switching of
reference through member variable, shall have 0 impact on the local
variable.


              Hence, "volatile" and "synchronized" should work. Just that I
am not sure on reader writer lock.

              Thanks and Regards
              Yan Cheng CHEOK


        --- On Fri, 2/4/11, Bob Hiestand <bob.hiestand at gmail.com> wrote:


          From: Bob Hiestand <bob.hiestand at gmail.com>
          Subject: Re: [concurrency-interest] Is it possible to prevent out
of order execution by using reader writer lock?
          To: "Yan Cheng CHEOK" <yccheok at yahoo.com>
          Date: Friday, February 4, 2011, 3:19 AM




          Yan,


            I am not an expert, but I'll take a stab.




          On Tue, Feb 1, 2011 at 8:36 AM, Yan Cheng CHEOK
<yccheok at yahoo.com> wrote:


            Solved by using volatile keyword
            ================================
            void fun_by_thread_1() {
               this.isNuclearFactory = true;
               this.factory = new NuclearFactory();
            }

            void fun_by_thread_2() {
               Factory _factory = this.factory;
               if (this.isNuclearFactory) {
                   // Do not operate nuclear factory!!!
                   return;
               }
               // If out-of-order execution happens, _factory might
               // be NuclearFactory instance.
               _factory.operate();
            }

            volatile Factory factory = new FoodFactory();
            volatile boolean isNuclearFactory = false;



          This does not work because both isNuclearFactory and factory can
be set by thread 1 after thread 2 has checked isNuclearFactory and before it
operates the factory.


            Solved by using synchronized keyword
            ====================================
            void fun_by_thread_1() {
               synchronized(this) {
                   this.isNuclearFactory = true;
                   this.factory = new NuclearFactory();
               }
            }

            void fun_by_thread_2() {
               synchronized(this) {
                   Factory _factory = this.factory;
                   if (this.isNuclearFactory) {
                       // Do not operate nuclear factory!!!
                       return;
                   }
               }
               // If out-of-order execution happens, _factory might
               // be NuclearFactory instance.
               _factory.operate();
            }

            Factory factory = new FoodFactory();
            boolean isNuclearFactory = false;


          This does not work because operate() is not called in the
synchronized block.  It could see a NuclearFactory if thread 1 executes
after the synchronized block in thread 2 completes.


            Solved by using Reader Writer Lock - Is this a correct way?
            ===========================================================
            void fun_by_thread_1() {
               writerLock.lock();
               try {
                   this.isNuclearFactory = true;
                   this.factory = new NuclearFactory();
               } finally {
                   writerLock.unlock();
               }
            }

            void fun_by_thread_2() {
               readerLock.lock();
               Factory _factory = this.factory;
               try {
                   if (this.isNuclearFactory) {
                       // Do not operate nuclear factory!!!
                       return;
                   }
               } finally {
                   readerLock.unlock();
               }

               // If out-of-order execution happens, _factory might
               // be NuclearFactory instance.
               _factory.operate();
            }

            Factory factory = new FoodFactory();
            boolean isNuclearFactory = false;
            private final java.util.concurrent.locks.Lock readerLock;
            private final java.util.concurrent.locks.Lock writerLock;




          This does not work in the same way that the synchronized approach
could fail.


          Thank you,


          bob

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20110204/932cd52f/attachment.html>


More information about the Concurrency-interest mailing list