java - 锁定两种方法但允许一种方法运行多线程

标签 java c# multithreading thread-safety locking

我有两种方法:

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

我想创建一个锁定:

  1. 当 Foo 中有线程运行时,Bar 上的线程将被锁定,直到 Foo 方法中没有线程时才能运行。

  2. Foo 中可以同时运行超过 1 个线程。

简单来说,锁定:“不允许同时运行 Foo 和 Bar,但允许 Foo 或 Bar 以多个线程运行”。

注意:简单的锁定不会解决问题,因为它会支持条件 1,但不会支持条件 2。

最佳答案

您只需要确保没有人正在执行其他方法,您可以通过计算每个方法有多少线程来实现这一点。 我没有使用锁,只是使用等待集和同步。

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 同时执行。

关于java - 锁定两种方法但允许一种方法运行多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25503985/

相关文章:

java - 列表的每个元素在函数之外都有相同的元素。

java - 通过 Java 运行 cmd 命令

java - Volatile:为什么要阻止编译器重新排序代码

c# - 从嵌套母版页访问用户控件

c# - 修复 C# 中的 A* 实现

java - 在终止状态线程上运行()

c++ - libSoX 是线程安全的吗?

java - Ivy、ant 和启动脚本

java - 无法找出ConcurrentModificationException的原因

c# - ResX 文件和额外的应用层