Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Многопоточность в java

RostikP Знаток (401), на голосовании 8 месяцев назад
мне поставлено такое задание, мол, есть три человека, они исполняют свою работу за 1 мин, 0.5 минут и 0.8 минут, они должны выполнить 450 задач и все вроде хорошо, но каждого рабочего надо засунуть в отдельный поток, я вроде бы все сделал как надо, но я сомневаюсь в том, что мой OUTPUT от программы верный. Пожалуйста скажите что не так.

 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 = 10000;

private Thread t;

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 (this) {
if (people < MAX_PEOPLE) {
time += worker_service_time;
workerTotalTime += worker_service_time;
people++;
}
}
}
synchronized (this) {
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();
}
}
Дополнен 9 месяцев назад
time by worker 1: 370.0
time by worker 2: 48.0
time by worker 3: 0.0
Total time: 418.0

time by worker 1: 450.0
time by worker 2: 0.0
time by worker 3: 0.0
Total time: 450.0

time by worker 1: 367.0
time by worker 2: 51.5
time by worker 3: 0.0
Total time: 418.5


по идее все потоки должны выполняться одновременно, но это не так, один поток выполняется большее количество времени, чем остальные, хотя я вроде попытался решить эту проблему с помощью синхронизации. НЕ понимаю. помогите.
Голосование за лучший ответ
Finyy Гуру (3900) 9 месяцев назад
Красивый код, за java не шарю
zero-two г Гуру (3182) 9 месяцев назад
Ты форумом ошибся. Тебе надо на другой ресурс.

Вбей вопрос в гугл и там будут форумы программистов.

Спроси там.
Татьяна Просветленный (36374) 9 месяцев назад
Ваша проблема заключается в том, что вы синхронизируете по объекту `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();
}
}
RostikPЗнаток (401) 9 месяцев назад
ага спс за код от нейросети, как будто сам не умею ей пользоваться......
Александр Искусственный Интеллект (301569) 9 месяцев назад
где в коде упоминается про "450 задач"?
RostikPЗнаток (401) 9 месяцев назад
написал в коде не 450, а 10000.
Sergio 2.1 Оракул (67281) 9 месяцев назад
 import java.util.concurrent.atomic.AtomicInteger; 

public class Wardrobe implements Runnable {

private double workerServiceTime;
private double workerTotalTime;
private static AtomicInteger people = new AtomicInteger(0);
private static double total_time;
final private static int MAX_PEOPLE = 450;

private Thread t;

public Wardrobe(double workerServiceTime, String name) {
this.workerServiceTime = workerServiceTime;
t = new Thread(this, name);
t.start();
}

public void run() {
while (people.get() < MAX_PEOPLE) {
if (people.incrementAndGet() <= MAX_PEOPLE) {
workerTotalTime += workerServiceTime;
}
}
}

public static synchronized void addToTotal(double time) {
total_time += time;
}

public static void main(String[] args) {
Wardrobe w1 = new Wardrobe(1.0, "Worker 1");
Wardrobe w2 = new Wardrobe(0.5, "Worker 2");
Wardrobe w3 = new Wardrobe(0.8, "Worker 3");

try {
w1.t.join();
w2.t.join();
w3.t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

addToTotal(w1.workerTotalTime);
addToTotal(w2.workerTotalTime);
addToTotal(w3.workerTotalTime);

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

Андрей Панарин Искусственный Интеллект (249271) 9 месяцев назад
Может быть смысл добавить рабочим задержку Thread.sleep, соответствующую времени работы каждого из них. А то время учитывается только в переменных и у каждого идет по-своему. Пока один проснулся, другой уже за это мгновение пять часов отработал. Не работники гардероба, а какие-то повелители времени.
Похожие вопросы