Java中的互斥方法执行

mil*_*lan 5 java multithreading synchronized

我有两种方法:a()b().虽然我有多个线程访问任何方法在同一时间(即理想)的罚款,我不希望任何线程进入a()b()被执行.我怎么做?

编辑1

让我们说有4个线程Thread 1正在访问A().我想要的是所有4个线程都不应该使用B().

ass*_*ias 6

检查底部的更新 - 我不认为这种方法可行.留下它作为信息.


你可以使用信号量:

  • 如果一个线程进入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();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

你的意图是不明确的,你的问题已经被编辑,因为您的意见一个说,你想a()b()相互排斥的(多个线程可以运行a()b()平行,但a()b()不应该并行运行).在这种情况下,您可以使用相同的逻辑和2个信号量inAinB.


UPDATE => BUG

正如@yshavit在对另一个答案的评论中指出的那样,在以下场景中代码中存在竞争条件:

  • T1运行a()并获得inB
  • T2运行b()并且无法获得inB
  • T1发布 inB
  • 虽然T2正在运行,T3仍会运行a()并设法获取inBb()

似乎只有Sempahores才能实现这一目标.这个答案提供了更好的解决方案