gpt4 book ai didi

java - 互斥方法

转载 作者:太空宇宙 更新时间:2023-11-04 11:13:18 26 4
gpt4 key购买 nike

我正在学习 Java 多线程编程。我有以下逻辑:

假设我有A级

class A {
ConcurrentMap<K, V> map;

public void someMethod1 () {
// operation 1 on map
// operation 2 on map
}

public void someMethod2 () {
// operation 3 on map
// operation 4 on map
}
}

现在我不需要同步“someMethod1”或“someMethod2”中的操作。这意味着如果有两个线程同时调用“someMethod1”,我不需要序列化这些操作(因为 ConcurrentMap 将完成这项工作)。

但我希望“someMethod1”和“someMethod2”是互斥的,这意味着当某个线程正在执行“someMethod1”时,另一个线程应该等待进入“someMethod2”(但应该允许另一个线程进入“someMethod1”)。

那么,简而言之,有没有一种方法可以使“someMethod1”和“someMethod2”不互斥,而是彼此互斥?

我希望我的问题表述得足够清楚......

谢谢!

最佳答案

我尝试了几次更高级别的构造,但什么也没想到。我认为这可能是一个下降到低级别 API 的机会:

EDIT: I actually think you're trying to set up a problem which is inherently tricky (see second to last paragraph) and probably not needed (see last paragraph). But that said, here's how it could be done, and I'll leave the color commentary for the end of this answer.

private int someMethod1Invocations = 0;
private int someMethod2Invocations = 0;

public void someMethod1() {
synchronized(this) {
// Wait for there to be no someMethod2 invocations -- but
// don't wait on any someMethod1 invocations.
// Once all someMethod2s are done, increment someMethod1Invocations
// to signify that we're running, and proceed
while (someMethod2Invocations > 0)
wait();
someMethod1Invocations++;
}

// your code here

synchronized (this) {
// We're done with this method, so decrement someMethod1Invocations
// and wake up any threads that were waiting for that to hit 0.
someMethod1Invocations--;
notifyAll();
}
}

public void someMethod2() {
// comments are all ditto the above
synchronized(this) {
while (someMethod1Invocations > 0)
wait();
someMethod2Invocations++;
}

// your code here
synchronized(this) {
someMethod2Invocations--;
notifyAll();
}
}

上述一个明显的问题是它可能导致 thread starvation 。例如,someMethod1() 正在运行(并阻塞 someMethod2()),就在它即将完成时,另一个线程出现并调用 someMethod1()。一切进展顺利,就在它完成时,另一个线程启动someMethod1(),依此类推。在这种情况下,someMethod2() 将永远没有机会运行。这实际上并不是上面代码中的直接错误;而是错误。这是一个与您的设计需求相关的问题,一个好的解决方案应该积极努力解决这个问题。我认为公平AbstractQueuedSynchronizer可以做到这一点,尽管这是留给读者的练习。 :)

最后,我忍不住要插入一个观点:鉴于 ConcurrentHashMap 操作非常快,您最好只在两个方法周围放置一个互斥锁,然后就可以完成它。所以,是的,线程必须排队才能调用 someMethod1(),但每个线程都会非常快地完成其轮次(从而让其他线程继续执行)。应该不是问题。

关于java - 互斥方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45761145/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com