锁定两个方法,但允许其中一个运行多线程
本文关键字:许其中 一个 运行 多线程 两个 方法 锁定 | 更新日期: 2023-09-27 18:19:23
我有两个方法:
Foo(){…}酒吧 () {...}
我想创建一个这样的锁:
-
当有一个线程在Foo中运行时,线程将被锁定在Bar上,并且在Foo方法中没有线程之前无法运行。
-
Foo中可以同时运行1个以上的线程
简单来说,锁:"不允许同时运行Foo和Bar,但允许Foo或Bar在多个线程中运行"。
您只需要确保没有人在执行其他方法,您可以通过计算每个方法有多少线程来存档。我不使用锁,只使用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同时执行。