我有两种方法:a()
and b()
。虽然我可以接受多个线程同时访问任何方法(这是可取的),但我不希望任何线程进入a()
while b()
正在被执行。
我怎么做?
Edit 1
假设有 4 个线程Thread 1
正在访问A()
。我想要的是所有 4 个线程都不应该使用B()
.
检查底部的更新- 我认为这种方法行不通。留下它以供参考。
你可以使用信号 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html:
- 如果一个线程在
b()
,一个尝试执行的线程a()
将阻塞直到执行b()
结束了。
- 如果一个线程在
b()
第二个线程尝试运行b()
它将能够
- 如果有2个线程执行
a()
while 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();
}
}
EDIT
您的意图不明确,您的问题已被编辑,因为您的评论之一说您想要a()
and b()
互斥(许多线程可以运行a()
or b()
并行,但是a()
and b()
永远不应该并行运行)。在这种情况下,您可以对 2 个信号量使用相同的逻辑inA
and inB
.
更新=>错误
正如 @yshavit 在评论中指出的另一个答案 https://stackoverflow.com/a/14133694/829571,在以下场景的代码中存在竞争条件:
- T1 runs
a()
并获得inB
- T2 runs
b()
并且未能获得inB
- T1发布
inB
- T3 runs
a()
并设法获得inB
尽管 T2 正在运行b()
看来仅用信号量无法实现这一点。这个答案给出了 https://stackoverflow.com/a/14134638/829571更好的解决方案。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)