Java wait() 和 notifyAll() 恢复最旧的线程

标签 java concurrency thread-safety

我的问题:

假设我有类 A 和一些变量 a

以及带有变量 prevnext 的类 B

在类A中,我想创建方法changeIfEqual(B myB)来检查是否A.a == my_B.prev,如果是的话我将 A.a 更改为 my_B.next。但是如果 A.a != my_B.prev 我希望线程 wait() 直到 continion 为真,然后执行等待时间最长的线程。

所以我想 A.changeIfEqual(B myB) 应该如下所示:

public synchronized void changeIfEqual(B myB){
  while(this.a != myB.b_prev){
     wait();
  }
  notifyAll();
}

在这种情况下,问题是如何确保最旧的线程将被恢复? (wait()notifyAll() 不提供该功能)

最佳答案

你不知道。哪个线程收到通知取决于调度程序。如果用ReentrantLock替换隐式锁(使用synchronized),那么就可以指定锁是公平的。但这并不是一个完美的解决方案,请参阅the API docs :

The constructor for this class accepts an optional fairness parameter. When set true, under contention, locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order. Programs using fair locks accessed by many threads may display lower overall throughput (i.e., are slower; often much slower) than those using the default setting, but have smaller variances in times to obtain locks and guarantee lack of starvation. Note however, that fairness of locks does not guarantee fairness of thread scheduling. Thus, one of many threads using a fair lock may obtain it multiple times in succession while other active threads are not progressing and not currently holding the lock. Also note that the untimed tryLock method does not honor the fairness setting. It will succeed if the lock is available even if other threads are waiting.

关于Java wait() 和 notifyAll() 恢复最旧的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58823049/

相关文章:

python - 使用 python 和依赖项进行多处理

c# - 跨作用域 DbContext 的并发

c# - 分配给方法的 ref 参数是原子操作吗?

concurrency - 并发使用MVC应用的Stack Empty问题

authentication - 使用Spring Security时,请求之间是否共享SecurityContext?

java - 如何更改全部大写的字符串以利用第一个字母然后是每个空格后面的第一个字母? ( java )

Java - 解析 JSON 时忽略无效记录的更好方法

java - OpenGL ES 应用程序和运行 native Java 代码

java - 在单个项目中混合 java 和 scala - 在 scala 中进行测试,在 java 中进行核心

java - 当有等待线程时如何优雅地降级程序?