java - 如何相互排除两个程序部分

标签 java multithreading concurrency

我遇到以下 Java 并发问题:

  1. 有两个函数,f1f2,它们可以由任何线程以任意顺序执行
  2. 允许多个线程同时执行f1
  3. 允许多个线程同时执行f2
  4. 如果f2正在由至少一个线程执行,则不允许任何线程执行f1,反之亦然f2

现在直接(次优)的实现是:

class AccessedByManyThreads {
  void doActionWithF1() {
    foo();
    synchronized (this) {
      f1();
    }
    bar();
  }
  void doActionWithF2() {
    baz();
    synchronized (this) {
      f2();
    }
    faz();
  }
}

此实现满足要求 4,但是它无法放宽允许的要求 2 和 3。实际上,我在这里需要类似 ReadWriteLock 的东西,其中不仅可以共享读锁,还可以共享写锁。

所以我的问题:

  1. 是否有任何 Java 并发库原语可以用来满足要求 2. 和 3.?
  2. 如果没有,实现的想法是什么?

最佳答案

我不确定是否有任何 Java 并发库可以在此用例中提供帮助。但是,您可以模拟类似于信号量变量的东西来实现此目的:

class AccessedByManyThreads {
    private int threadsAccessingF1;
    private int threadsAccessingF2;

    public AccessedByManyThreads() {
        this.threadsAccessingF1 = 0;
        this.threadsAccessingF2 = 0;
    }

    public void doActionWithF1() {
        synchronized(this) {
            if(threadsAccessingF2 > 0) {
                return;    
                // some function(s) are accessing f2, so return without calling f1()
            }
            else {
                threadsAccessingF1++;
            }
        }
        f1();
        synchronized(this) {
            threadsAccessingF1--;
        }
    }

    public void doActionWithF2() {
        synchronized(this) {
            if(threadsAccessingF1 > 0) {
                return;    
                // some function(s) are accessing f1, so return without calling f2()
            }
            else {
                threadsAccessingF2++;
            }
        }
        f2();
        synchronized(this) {
            threadsAccessingF2--;
        }
    }
}

关于java - 如何相互排除两个程序部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43706806/

相关文章:

Java同步方法锁定对象还是方法?

c++ - GDB 报告的额外线程是怎么回事?

python - "Pythonic"多线程(并发)语言

java - 如何通过 HQL 获取 map

java - 重复向ArrayList添加数据

java - 使用javascript修改固定在顶部的元素的css属性

java - wsgen 引发 NoClassDefFoundError 异常

windows - 无论如何,我无法让这个进度条从线程更新

java - Java 中有对象的原子包装吗?

concurrency - esper和update listener并发