我有两种方法:a()b()。尽管我可以让多个线程同时访问任何方法(这是理想的),但我不希望任何线程在执行a()时输入b()
我怎么做?

编辑1

可以说有4个线程,并且Thread 1正在访问A()。我想要的是所有4个线程都不应该使用B()

最佳答案

底部的CHECK UPDATE-我认为这种方法行不通。留作引用。

您可以使用Semaphore:

  • 如果线程在b()中,则尝试执行a()的线程将阻塞,直到b()的执行结束。
  • 如果一个线程在b()中,并且第二个线程尝试运行b(),它将能够
  • 如果2个线程在未执行a()时执行b(),则两个线程都将运行

  • 注意:一旦一个线程进入a()并通过了“信号量测试”,则另一个线程可以在b()结束之前开始运行a()

    该原理应该可行,但我尚未对其进行测试。
    private final Semaphore inB = new Semaphore(1);
    
    public void a() throws InterruptedException {
        inB.acquire(); //blocks until no thread is in b any longer
        //now we are good to go and execute a()
        //release the semaphore immediately for other threads who want to run a()
        inB.release();
        //rest of your code here
    }
    public void b() {
        //does not block to allow 2 thread running b() simultaneously
        boolean needToRelease = inB.tryAcquire();
        //rest of your code
        //if the permit was acquired, release it to allow threads to run a()
        if (needToRelease) {
            inB.release();
        }
    }
    

    编辑

    您的意图不明确,您的问题已被编辑,因为您的评论之一表明您希望a()b()是互斥的(许多线程可以并行运行a()b(),但是永远不要并行运行a()b()) 。在这种情况下,可以对2个信号量inAinB使用相同的逻辑。

    更新=>错误

    如@yshavit在对another answer的注释中所指出的,在以下情况下代码中存在竞争条件:
  • T1运行a()并获取inB
  • T2运行b(),但无法获取inB
  • T1发布inB
  • 尽管T2正在运行a()
  • ,但T3运行inB并设法获取b()
    似乎仅靠Sempahores不可能做到这一点。 This answer gives是一个更好的解决方案。

    10-04 18:56