锁定两个方法,但允许其中一个运行多线程

本文关键字:许其中 一个 运行 多线程 两个 方法 锁定 | 更新日期: 2023-09-27 18:19:23

我有两个方法:

Foo(){…}酒吧 () {...}

我想创建一个这样的锁:

  1. 当有一个线程在Foo中运行时,线程将被锁定在Bar上,并且在Foo方法中没有线程之前无法运行。

  2. Foo中可以同时运行1个以上的线程

简单来说,锁:"不允许同时运行Foo和Bar,但允许Foo或Bar在多个线程中运行"。

锁定两个方法,但允许其中一个运行多线程

注意:简单的锁定不会达到这个目的,因为它会维持条件1,但不会维持条件2。

您只需要确保没有人在执行其他方法,您可以通过计算每个方法有多少线程来存档。我不使用锁,只使用waitset和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();
    }
}

"while(numbar != 0) this.wait()"是必要的,因为notifyAll()的工作方式。如果没有它,可能会发生另一个线程在我们解锁并试图进入foo的线程到达foo++之前开始执行bar的情况,导致bar和foo同时执行。

相关文章: