Ответы Mail.ru: Многопоточность в java

Ваша проблема заключается в том, что вы синхронизируете по объекту `this`, который является экземпляром класса `Wardrobe`. Это означает, что каждый поток, который запускает метод `run()`, должен ждать, пока другой поток освободит блокировку на этом объекте. Таким образом, вы фактически делаете свою программу последовательной, а не параллельной.

Чтобы решить эту проблему, вам нужно синхронизировать по общему ресурсу, который используется всеми потоками, а именно переменной `people`. Вы можете сделать это, используя статический объект `lock`, который будет служить монитором для синхронизации.

исправленный код:

 public class Wardrobe implements Runnable {  
  
    private double worker_service_time;  
    private double workerTotalTime;  
  
    private static int people = 0;  
    private static double total_time;  
  
    final private int MAX_PEOPLE = 450; // Изменил на 450, так как в задании так 
  
    private Thread t;  
  
    private static final Object lock = new Object(); // Объект для синхронизации 
  
    public Wardrobe(double worker_service_time, String name) {  
        this.worker_service_time = worker_service_time;  
        t = new Thread(this, name);  
        t.start();  
    }  
  
    public void run() {  
        double time = 0;  
        while (people < MAX_PEOPLE) {  
            synchronized (lock) { // Синхронизируем по lock 
                if (people < MAX_PEOPLE) {  
                    time += worker_service_time;  
                    workerTotalTime += worker_service_time;  
                    people++;  
                }  
            }  
        }  
        synchronized (lock) { // Синхронизируем по lock 
            total_time += time;  
        }  
    }  
  
    public static void main(String[] args) {  
        Wardrobe w1 = new Wardrobe(1.0, "1");  
        Wardrobe w2 = new Wardrobe(0.5, "2");  
        Wardrobe w3 = new Wardrobe(0.8, "3");  
  
        Thread outputThread = new Thread(() -> {  
            try {  
                w1.t.join();  
                w2.t.join();  
                w3.t.join();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
  
            System.out.println("time by worker 1: " + w1.workerTotalTime);  
            System.out.println("time by worker 2: " + w2.workerTotalTime);  
            System.out.println("time by worker 3: " + w3.workerTotalTime);  
            System.out.println("Total time: " + total_time);  
        });  
  
        outputThread.start();  
    }  
}