【问题标题】:How to create fair lock to solve starvation in java?java - 如何创建公平锁来解决java中的饥饿问题?
【发布时间】:2014-07-07 00:07:41
【问题描述】:

我想创建公平锁,以便每个线程一个接一个地获得锁,而不管优先级如何。

import java.util.concurrent.locks.ReentrantLock;

public class StarvationRunnable implements Runnable {

    private ReentrantLock lock = new ReentrantLock(true);

    public void doLongTask() {
        lock.lock();
        // to imitate long running task in critical section
        for (int i = 0; i < 1000000000; i++)
            ;
        System.out.println(Thread.currentThread().getName() + " is running with priority "
                + Thread.currentThread().getPriority() + " !");
        lock.unlock();
    }

    @Override
    public void run() {
        for (;;) {
            doLongTask();
        }
    }

    public static void main(String[] args) {
        StarvationRunnable runnable = new StarvationRunnable();

        for (int i = 0; i < 4; i++) {
            Thread thread = new Thread(runnable);
            thread.setPriority(i == 3 ? Thread.MIN_PRIORITY : Thread.MAX_PRIORITY);
            thread.start();
        }
    }
}

所以我有 4 个线程。 3 具有最高优先级,1 具有最低优先级。我通过

创建公平锁
new ReentrantLock(true);

当我运行这个演示时,它不会让具有最小优先级的线程执行与具有最大优先级的线程一样多的执行次数。但我认为公平锁就是为了这个。

如何正确使用公平锁?

【问题讨论】:

  • 这意味着每个线程被顺序地赋予一个锁,以便每个线程可以运行同步方法相同的次数。
  • @Volodia:这不是文档定义公平性的方式:“当设置为 true 时,在争用情况下,锁定有利于授予对等待时间最长的线程的访问权限。”
  • JIT 不会优化这样的循环吗?

标签: java concurrency reentrantlock


【解决方案1】:

公平与线程优先级无关。 The javadoc 说:

这个类的构造函数接受一个可选的公平参数。当设置为 true 时,在争用情况下,锁有利于授予对等待时间最长的线程的访问权限。

另一方面,线程优先级是对本机线程调度程序的提示,以便在高优先级线程争用 CPU 时间时为高优先级线程提供比低优先级线程更多的 CPU 时间。

【讨论】:

  • 当我运行 demo 时,优先级较低的线程不像高优先级的线程那样获得锁。但是文档说granting access to the longest-waiting thread
  • 为什么公平锁不会像给予最高优先级的线程一样多次给予最低优先级线程的锁?
  • 因为它做了文档所说的事情:给等待时间最长的线程锁。由于具有最高优先级的线程比具有最低优先级的线程拥有更多的 CPU 访问权限,因此具有高优先级的线程实际执行请求锁的指令的机会更大。例如,最高优先级线程可以被调度 100 次,并在最低优先级线程被调度之前运行长任务 100 次,因此有机会申请锁。
  • 另外,请注意,您的循环很有可能被 JIT 完全消除,JIT 足够聪明,可以检测到代码什么都不做并将其优化掉。
  • 谢谢!难道你不知道不使用优先级在简单的演示中编写饥饿代码的方法吗?
【解决方案2】:

我使用 java wait()notify() 框架创建了一个示例实现。它提供基于先到先服务 (FCFS) 的锁,而与线程优先级无关。

您可以在https://github.com/nenapu/JavaLocks查看公平锁实现

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2014-03-13
    • 1970-01-01
    相关资源
    最近更新 更多