ZiviMagic
ZiviMagic

Reputation: 1054

Locking two methods but allowing one to run multy threaded

I have two methods:

Foo() {...} Bar() {...}

I want to create a locking such that:

  1. While there is a thread running in Foo, Threads will be locked on Bar and not able to run until there are no threads in Foo method.

  2. There can be more than 1 thread running at the same time in Foo.

In simple words, locking: "To not allow running Foo and Bar simultaniously but allowing Foo or Bar to run with more than one thread".

Note: Simple locking won't do the trick as it will uphold condition 1 but it will not uphold condition 2.

Upvotes: 1

Views: 93

Answers (1)

Mognom
Mognom

Reputation: 214

You just need to make sure none is executing the other method, you can archieve this by counting how many threads are at each method. Im not using locks tho, just waitsets and synchronized.

int numFoo = 0;
int numBar = 0;

void foo(){
    enter(0);
    //stuff
    leave(0);
}

void bar(){
    enter(1);
    //Stuff
    leave(1);
}

//Synchronized makes no more than one thread can run this simultaneously, so they wont be any race condition
synchronized void enter(int id){
    //If it was foo entering
    if (id == 0){
        while(numBar != 0)//Waits until theres none executing bar
            try {
                this.wait();
            } catch (InterruptedException e) {e.printStackTrace();}
        numFoo++;//Enters
    }
    else{
        while(numFoo !=0)//Waits until none executes foo
            try { 
                this.wait();
            } catch (InterruptedException e) { e.printStackTrace();}
        numBar++;//Enters
    }
}

synchronized void leave(int id){
    if (id == 0){
        numFoo--;
        if(numFoo == 0)//If it was the last executing foo unlocks the others
            this.notifyAll();
        }
    else{
        numBar--;
        if(numBar == 0)//If it was the last executing bar unlocks the others
            this.notifyAll();
    }
}

The "while(numbar != 0) this.wait()" it's necessary as how the notifyAll() works. Without it it may happen that another thread starts executing bar before the threads that we unlocked and were trying to enter foo reach the foo++, resulting in having bar and foo executed at the same time.

Upvotes: 3

Related Questions