Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fair vs NonFair

I have been tested fair and non fair disciplines via RentrantLock. I wrote a small program that simulates dinning philosophers.

Each philospher has left and right fork which are ReentrantLocks. I have simulated 1000 times act of thinking and eating:

 for (int i = 0; i < ACT_TIMES; i++) {
            act();
        }

where act is

private void act() {
        think();
        eat();

    }

Think is not interesting it just sleeps for some amount of time. Here is eat method

private void eat() {
        try {
            if (left.tryLock(0, TimeUnit.MILLISECONDS)) {
                if (right.tryLock(0, TimeUnit.MILLISECONDS)) {
                    log("eating");
                    eatCount++;
                    try {
                        Thread.sleep(EAT_TIME);
                    } catch (InterruptedException e) {
                    } finally {
                        left.unlock();
                        right.unlock();
                    }
                } else {
                    left.unlock();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

Main method:

 Lock[] forks = new Lock[5];
        for (int i = 0; i < forks.length; i++) {
            forks[i] = new ReentrantLock();
        }
        Philosopher p1 = new Philosopher(0, forks[1], forks[0]);
        Philosopher p2 = new Philosopher(1, forks[2], forks[1]);
        Philosopher p3 = new Philosopher(2, forks[3], forks[2]);
        Philosopher p4 = new Philosopher(3, forks[4], forks[3]);
        Philosopher p5 = new Philosopher(4, forks[0], forks[4]);
        ExecutorService exec = Executors.newFixedThreadPool(5);
        exec.submit(p1);
        exec.submit(p2);
        exec.submit(p3);
        exec.submit(p4);
        exec.submit(p5);

After all 5 threads finishes, I print eatCount for each philosopher. And these values don't differ too much for fair(new ReentrantLock(true)) and unfair(new ReentrantLock()) discipline.

(first number is a number of a philospher)

Fair lock:

0 344
1 348
2 366
3 359
4 363
Total number of eating 1780

Unfair Lock:

0 338
1 338
2 339
3 341
4 352
Total number of eating 1708

I have expected some starvation for unfair lock, I mean some philosopher/philosophers have to have eatCount much greater than others, but starvation didn't happen. why?

like image 479
maks Avatar asked Dec 17 '12 17:12

maks


People also ask

What is the difference between unfair and fair?

A 'fair' dismissal is predominantly based on an employee's conduct, so, unfortunately, there are some situations where a company is well within their rights to dismiss an employee. Unfair dismissal is more complicated but includes situations such as firing an employee because they are pregnant.

Is life fair or unfair?

Most of us would say that life is not always fair. We have our own set of grouses against people, events, occurrences and circumstances. But every one of us would like to believe that natural justice does exist. As and when someone insults us or does harm to another, we want justice.

What is fairness How do you know when something is fair or unfair?

Fairness is when everyone is treated equally and no one is left out. People that are fair follow the rules in sports, games, activities, and in their community. They are honest and trustworthy. They follow Eleanor Roosevelt's quote “It is not fair to ask of others what you are unwilling to do yourself.”

Is Fair always equal?

What is the difference between fair and equal? Fairness means treating people according to their needs. This does not always mean it will be equal. Equality means treating everyone exactly the same.


2 Answers

The thread which releases a lock has a much better chance of regaining the lock as it is busy while the other threads could be blocked. Busy waiting won't show this as each thread will have an equal chance of grabbing the lock. Possibly the one to release the lock could be at a slight disadvantage.

final ReentrantLock lock = new ReentrantLock();
for (int i = 0; i < 5; i++) {
    final int finalI = i;
    new Thread(new Runnable() {
        @Override
        public void run() {
            for (int j = 0; j < 5; j++) {
                lock.lock();
                System.out.println("locked by " + finalI);
                lock.unlock();
            }
        }
    }).start();
}

prints

locked by 0
locked by 0
locked by 0
locked by 0
locked by 0
locked by 1
locked by 1
locked by 1
locked by 1
locked by 1
locked by 2
locked by 2
locked by 2
locked by 2
locked by 2
locked by 3
locked by 3
locked by 3
locked by 3
locked by 3
locked by 4
locked by 4
locked by 4
locked by 4
locked by 4

but if I make the lock fair with true I see

locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
locked by 0
locked by 1
locked by 2
locked by 3
locked by 4
like image 51
Peter Lawrey Avatar answered Sep 20 '22 15:09

Peter Lawrey


remove all sleep(), you may see some unfairness.

like image 29
irreputable Avatar answered Sep 19 '22 15:09

irreputable