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

Yan Cheng CHEOK yccheok at yahoo.com
Thu Feb 3 14:29:14 EST 2011


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/20110203/4a186ac9/attachment.html>


More information about the Concurrency-interest mailing list