Многопоточность Java: как предотвратить одновременное воспроизведение логики между двумя потоками?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Многопоточность Java: как предотвратить одновременное воспроизведение логики между двумя потоками?

Сообщение Anonymous »

Я создал класс Fish, который имитирует рыбу, воспроизводящуюся в программе Java. Каждая рыба должна размножаться, встречая другую случайную рыбу. Но проблема в том, что две рыбки находят друг друга как пару и одновременно рожают двух детей. Этот процесс размножения повторяется несколько раз одновременно.
Рыбок держу в классе Аквариум. После рождения рыбки, после достижения ею репродуктивного возраста (т.е. должно начинаться с 4 лет), она должна найти случайного партнера из класса Аквариум. Но в коде, который я написал, рыба хочет найти себе пару и размножиться, и в этот момент эта рыба также размножается, выбирая первую рыбу из класса Аквариум. Две рыбки родятся в одном месте моря. На самом деле должна родиться одна рыбка. Я не могу понять, как решить эту проблему. Настоящая проблема заключается в методе воспроизводства. Где и как это написать. Подскажите пожалуйста оптимальные решения. Заранее всем спасибо за ответы.
У меня есть урок по рыбалке:

Код: Выделить всё

package lesson.uz;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

import java.util.Random;

@Getter
@Setter
@EqualsAndHashCode
public class Fish extends Thread {

private long id;
private Gender gender;
private Integer lifespan;
private String fishName;
private Integer age = 0;
private static Long counter = 1L;

public Fish(Gender gender) {
this.gender = gender;
this.lifespan = new Random().nextInt(11)+40;
this.fishName = "Fish"+ counter++;
this.id = Math.abs(new Random().nextLong() * System.currentTimeMillis());
System.out.println(fishName + " created.  "+System.currentTimeMillis());
}

@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
reproduce();
age++;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

}

public void reproduce() {
Fish randomFish = getRandomFish();
long count = Aquarium.raddom.stream().filter(id -> randomFish.getId() == id || this.getId() == id).count();

if (count == 0 && this.age >= 4 && randomFish.getAge() >= 4 && this.getGender() != randomFish.getGender()) {

Aquarium.raddom.add(this.id);
Aquarium.raddom.add(randomFish.id);

System.out.println(this.fishName + " and " + randomFish.getFishName() + " meet.\n");
Fish babyFish = createFish();
Aquarium.fishList.add(babyFish);
Aquarium.raddom.remove(this.id);
Aquarium.raddom.remove(randomFish.id);
}
}

public static Fish createFish() {
Fish newFish = new Fish(Math.random() > 0.5 ? Gender.MALE : Gender.FEMALE);
newFish.start();
return newFish;
}

public Fish getRandomFish() {
int randomNum = 0;
Fish currenFish = null;
while (true) {
randomNum = new Random().nextInt(Aquarium.fishList.size());
currenFish = Aquarium.fishList.get(randomNum);

if (this != currenFish) {
break;
}
}
return currenFish;
}
}
У меня есть класс Аквариума:

Код: Выделить всё

package lesson.uz;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Aquarium extends Thread {

public static List fishList = new ArrayList();
public static List raddom = new ArrayList();

@Override
public void run() {

}
}
и Основной класс:

Код: Выделить всё

package lesson.uz;

public class Main {

public static void main(String[] args) {
Aquarium aquarium = new Aquarium();
aquarium.start();
init();
}

public static void init() {
Fish fish1 = new Fish(Gender.MALE);
fish1.start();
Aquarium.fishList.add(fish1);
Fish fish2 = new Fish(Gender.FEMALE);
fish2.start();
Aquarium.fishList.add(fish2);
}
}
Проблема (Проблема):
Рыба А и Рыба Б выбирают друг друга в качестве партнёра.
В то же время Рыба Б также выбирает Рыбу А и начинает Процесс воспроизводства идет параллельно.
В результате одновременно рождаются двое детей.
Вопрос:
Как решить эту проблему? Как обеспечить, чтобы процесс воспроизводства происходил только один раз?

Код: Выделить всё

public static List raddom = new ArrayList();
Я попробовал решить проблему, добавив случайный (в смысле роддом) список. Моя программа еще не закончена. Но это не помогло. Пожалуйста, предложите мне оптимальные решения.

Подробнее здесь: https://stackoverflow.com/questions/792 ... etween-two
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»