How to create fair lock to solve starvation in java?

Volodymyr Levytskyi picture Volodymyr Levytskyi · May 19, 2014 · Viewed 8.2k times · Source

I want to create fair lock so that each thread was given a lock one after the other regardless of priorities.

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();
        }
    }
}

So I have 4 threads. 3 with max priority and 1 with min priority. I create fair lock by

new ReentrantLock(true);

When I run this demo it doesn't give thread with min priority to execute as many times as to threads with max priority. But I think that fair lock is just for that.

How to use fair lock correctly?

Answer

JB Nizet picture JB Nizet · May 19, 2014

Fairness has nothing to do with thread priorities. The javadoc says:

The constructor for this class accepts an optional fairness parameter. When set true, under contention, locks favor granting access to the longest-waiting thread.

On the other hand, thread priorities are hints to the native thread scheduler in order to give more CPU time to high-priority threads than for low-priority threads if they are competing to get CPU time.