Java中的互斥方法执行
我有两种方法:Java中的互斥方法执行,java,multithreading,synchronized,Java,Multithreading,Synchronized,我有两种方法:a()和b()。虽然我可以让多个线程同时访问任何方法(这是可取的),但我不希望任何线程在执行b()时进入a()。 我该怎么做 编辑1 假设有4个线程,线程1正在访问A()。我想要的是,所有4个线程都不应该使用B()。留作参考 您可以使用: 如果线程位于b()中,则尝试执行a()的线程将阻塞,直到b()的执行结束 如果一个线程在b()中,而另一个线程试图运行b()它将能够 如果两个线程执行a(),而b()未执行,则两个线程都将运行 注意:一旦一个线程在a()中并通过了“信号量测
a()
和b()
。虽然我可以让多个线程同时访问任何方法(这是可取的),但我不希望任何线程在执行b()
时进入a()
。
我该怎么做
编辑1
假设有4个线程,
线程1
正在访问A()。我想要的是,所有4个线程都不应该使用B()。留作参考
您可以使用:
- 如果线程位于
b()
中,则尝试执行a()
的线程将阻塞,直到b()
的执行结束
- 如果一个线程在
b()
中,而另一个线程试图运行b()
它将能够
- 如果两个线程执行
a()
,而b()
未执行,则两个线程都将运行
注意:一旦一个线程在a()
中并通过了“信号量测试”,另一个线程就可以在a()
结束之前开始运行b()
这个原则应该行得通,但我还没有测试过
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()
不应该并行运行)。在这种情况下,您可以对两个信号量inA
和inB
使用相同的逻辑
更新=>BUG
正如@yshavit在对的注释中指出的,在以下场景中,代码中存在竞争条件:
- T1运行
a()
并获取inB
- T2运行
b()
- T1发布
inB
- T3运行
a()
并设法获取inB
,而T2运行b()
这似乎仅仅用Sempahores是无法实现的。更好的解决方案。是一个包含多个锁的Java包
在a()
中,以及a()的末尾
在b()
中,对相同的锁执行相同的操作
如果要处理不对称行为,可以使用a,a()是读卡器,b()是写卡器:几个b()锁,但几个a()锁不锁 为简单起见,建议使用异常处理:
public class Test {
private final Object lock = new Object();
private int counterA;
private int counterB;
public void a() {
synchronized(lock) {
while(counterB > 0) {
lock.wait();
}
++counterA;
}
// do work
synchronized(lock) {
--counterA;
lock.notifyAll();
}
}
public void b() {
synchronized(lock) {
while(counterA > 0) {
lock.wait();
}
++counterB;
}
// do work
synchronized(lock) {
--counterB;
lock.notifyAll();
}
}
}
在a()
的末尾调用b()
我想这不是问题所在。在使用b()
时,不允许执行线程a()
。b()
是否修改基础资源?你在找一个吗?我不希望任何线程在执行b()时输入a()
意味着如果线程a正在访问a()
,那么你不希望线程b使用b()
?这就是你想要的吗?如果是,请告诉我们你到底想做什么。也许我们可以帮你。我闻到,你的代码中有可疑的东西,那么当执行a()
时会发生什么情况呢?是否允许任何其他线程输入b()
?这是synchronize将执行的操作,而不是OP正在查找的操作。请查看对我的评论的答复?我不明白OP想做什么。如果线程A正在访问A(),那么OP不希望线程B使用B(),如果第一个线程通过A()
的信号量锁定和解锁会怎么样。上下文切换。线程2跳入b()
。它开始执行b()
。执行上下文开关A()
。这不正是我们想要避免的情况吗?a和b是并行执行的?@coding.mof我在回答中包括了这个案例。最初的问题是:“我不希望任何线程在执行b()时输入a()。因此,一旦您输入了a()
,因为没有线程运行b()
,您就没事了。