Java 如何相互排除两个程序段
我有以下Java并发问题:Java 如何相互排除两个程序段,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有以下Java并发问题: 有两个函数,f1和f2,可以由任何线程以任意顺序执行 允许多个线程同时执行f1 允许多个线程同时执行f2 如果至少有一个线程正在执行f2,则不允许任何线程执行f1,反之亦然,如果f2 现在,简单(次优)的实现是: class AccessedByManyThreads { void doActionWithF1() { foo(); synchronized (this) { f1(); } bar(); } v
class AccessedByManyThreads {
void doActionWithF1() {
foo();
synchronized (this) {
f1();
}
bar();
}
void doActionWithF2() {
baz();
synchronized (this) {
f2();
}
faz();
}
}
此实现满足需求4,但它不利用需求2允许的松弛。三,。实际上,我需要像ReadWriteLock这样的东西,在这里不仅可以共享读锁,还可以共享写锁
所以我的问题是:
我不确定是否有任何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并发库在这个用例中会有所帮助。但是,您可以模拟类似于信号量变量的内容来实现这一点:
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--;
}
}
}
public class TrafficLight<T> {
private ReentrantLock lock = new ReentrantLock(true);
private Condition switched = lock.newCondition();
private int registered;
private int maxBeforeYield = 20;
private T state;
public void acquire(T t) throws InterruptedException {
lock.lock();
try {
while ((state != null && !state.equals(t)) || maxBeforeYield == 0) {
switched.await();
}
if (state == null) {
state = t;
}
registered++;
maxBeforeYield--;
} finally {
lock.unlock();
}
}
public void release() {
lock.lock();
try {
registered--;
if (registered == 0) {
state = null;
maxBeforeYield = 20;
switched.signalAll();
}
} finally {
lock.unlock();
}
}
}
公共级交通灯{
private ReentrantLock lock=new ReentrantLock(true);
私有条件切换=lock.newCondition();
私人注册;
private int maxBeforeYield=20;
私有的T型国家;
公共无效获取(T T)抛出中断异常{
lock.lock();
试一试{
while((state!=null&&!state.equals(t))| | maxBeforeYield==0){
switched.wait();
}
if(state==null){
状态=t;
}
注册++;
最大收益率--;
}最后{
lock.unlock();
}
}
公开无效释放(){
lock.lock();
试一试{
注册--;
如果(已注册==0){
state=null;
maxBeforeYield=20;
switched.signalAll();
}
}最后{
lock.unlock();
}
}
}
创建trafficLight,并使尝试调用f1()的方法获取状态“f1”,以及尝试调用f2()的方法获取状态“f2”(显然可以使用其他状态对象)
如前所述,只要20个或更多线程正在等待不同的状态,该类就会强制进行状态切换。这基本上相当于将两个方向都设置为红灯,然后在十字路口通行后将另一个方向设置为绿灯
public class TrafficLight<T> {
private ReentrantLock lock = new ReentrantLock(true);
private Condition switched = lock.newCondition();
private int registered;
private int maxBeforeYield = 20;
private T state;
public void acquire(T t) throws InterruptedException {
lock.lock();
try {
while ((state != null && !state.equals(t)) || maxBeforeYield == 0) {
switched.await();
}
if (state == null) {
state = t;
}
registered++;
maxBeforeYield--;
} finally {
lock.unlock();
}
}
public void release() {
lock.lock();
try {
registered--;
if (registered == 0) {
state = null;
maxBeforeYield = 20;
switched.signalAll();
}
} finally {
lock.unlock();
}
}
}
公共级交通灯{
private ReentrantLock lock=new ReentrantLock(true);
私有条件切换=lock.newCondition();
私人注册;
private int maxBeforeYield=20;
私有的T型国家;
公共无效获取(T T)抛出中断异常{
lock.lock();
试一试{
while((state!=null&&!state.equals(t))| | maxBeforeYield==0){
switched.wait();
}
if(state==null){
状态=t;
}
注册++;
最大收益率--;
}最后{
lock.unlock();
}
}
公开无效释放(){
lock.lock();
试一试{
注册--;
如果(已注册==0){
state=null;
maxBeforeYield=20;
switched.signalAll();
}
}最后{
lock.unlock();
}
}
}
创建trafficLight,并使尝试调用f1()的方法获取状态“f1”,以及尝试调用f2()的方法获取状态“f2”(显然可以使用其他状态对象)
如前所述,只要20个或更多线程正在等待不同的状态,该类就会强制进行状态切换。这基本上相当于将两个方向都设置为红灯,然后在十字路口通行后将另一个方向设置为绿灯。您需要它做什么?如果只是用锁定实现规则,那么结果是不稳定的——只要有线程执行F1,就没有人执行F2,反之亦然。您可能需要一个在F1和F2之间切换的策略,该策略需要根据您的实际使用情况进行通知case@MattTimmermans“只要有线程执行F1,就没有人会执行F2”-在我的用例中这很好。我所做的是对f1的突然调用,然后在f2的一段时间之后。然而,它们可以随着时间的推移而被涂抹,但仍然保持着突发性。由于f1(f2)实现的并发性保证,多线程在不锁定的情况下调用f1()(或f2())是可以的,但是由于f1的正确性问题,我不能允许执行f2。您需要它做什么?如果只是通过锁定实现规则,那么结果是不稳定的——只要