Why doesn't sync work properly in this code?

Over the past few days I have been reading articles on Multithreading, and I have come across a simple task using multhithreading. This is the task:

Create an application that simulates a running race of 50 meters (in my code they are 10, it does not matter). The number of runners should be 5, and you should name each running stream. Print the winner. All other threads must also complete the race. Print the time spent by each runner to complete the race and set aside the time of the winner.

This is the code I wrote:

public class Racer implements Runnable {
    public static String winner;
    public static int time = 0;

    public void incrementTime() {
        synchronized (Racer.class) {
            time++;
        }
    }
    public void race() {
        for (int distance = 1; distance <= 10; distance++) {
            incrementTime();
            System.out.println("Distance covered by " + Thread.currentThread().getName() + " is " + distance + " meters.");
            boolean finalDest = this.isTheRaceOver(distance);
            if (finalDest) {
                break;
            }
        }
    }
    private boolean isTheRaceOver(int finalDistance) {
        boolean isRaceOver = false;
        if (Racer.winner == null && finalDistance == 10) {
            String winnerName = Thread.currentThread().getName();
            Racer.winner = winnerName;
            System.out.println("The winner is : " + Racer.winner + " with time " + time);
            isRaceOver = true;
        } else if (Racer.winner == null) {
            isRaceOver = false;
        } else if (finalDistance != 10) {
            isRaceOver = false;
        } else if (finalDistance == 10) {
            System.out.println(Thread.currentThread().getName() + " is with time " + time);
        }
        return isRaceOver;
    }
    @Override
    public void run() {
        this.race();
    }
}

public class RacerDemo {
    public static void main(String[] args) {
        Racer racer = new Racer();
        Thread a = new Thread(racer, "A");
        Thread b = new Thread(racer, "B");
        Thread c = new Thread(racer, "C");
        Thread d = new Thread(racer, "D");
        Thread e = new Thread(racer, "E");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
    }
}

One way out:

Distance covered by A is 1 meters. 
Distance covered by C is 1 meters. 
Distance covered by C is 2 meters. 
Distance covered by C is 3 meters.
Distance covered by C is 4 meters.
Distance covered by C is 5 meters.
Distance covered by C is 6 meters.
Distance covered by C is 7 meters.
Distance covered by C is 8 meters.
Distance covered by C is 9 meters.
Distance covered by C is 10 meters.
The winner is : C with time 12  // should be 11 ?
Distance covered by B is 1 meters.
Distance covered by B is 2 meters. 
...... and so on

, , - , (), , . incrementTime() , . , ? ?

+4
4

, . , , , .

race Raner Runnable, static time, .

+2

time . , , , :

  • 1 race() 0
  • 1 incrementTime() 1
  • 2 race() 1
  • 2 incrementTime() 2

time . , time race(), .

+1

, . Runner C isRaceOver. c 11, b , 1. c 12 . , , , IsTheRaceOver .

0

, , . , .

, , 1 .
, C, 1 .
, C, 2 .
...
: C 12// 11?

, . , , . , incrementTime isTheRaceOver , , .

: , , . volatile, , , . , , .

, volatile ( ), , .

0

Source: https://habr.com/ru/post/1655753/


All Articles