我创建了一个 Fish 类,它模拟在 Java 程序中繁殖的鱼。每条鱼必须通过遇到另一条随机鱼来繁殖。但问题是两条鱼作为一对找到彼此并同时生出两个孩子。这个繁殖过程同时重复多次。
我在水族馆课上养鱼。鱼出生后,达到繁殖年龄(即应从4岁开始)后,它应该从水族类中随机寻找配偶。但在我编写的代码中,一条鱼想要寻找配偶并繁殖,此时,该鱼也通过选择 Aquarium 类中的第一条鱼来繁殖。两条鱼会在海的一处诞生。事实上,应该诞生一条鱼。我不知道如何解决这个问题。真正的问题在于繁殖方法。在哪里以及如何写。请建议我最佳解决方案。先谢谢大家的回复了。
我有一个鱼课:
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<Fish> fishList = new ArrayList<>();
public static List<Long> 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);
}
}
问题(问题): 鱼A和鱼B互相选择作为配偶。 与此同时,鱼B也选择了鱼A,并开始并行的繁殖过程。 结果,同时创建了两个孩子。
问题: 如何解决这个问题呢?如何确保复制过程一次只发生一次?
public static List<Long> raddom = new ArrayList<>();
我尝试通过添加 raddom(产房意义上的)列表来解决问题。我的程序还没有完成。但这没有帮助。请给我建议最佳解决方案。
高水平
我将从 Fish 类中删除繁殖方法并将其放置在 Aquarium 类中。当鱼足够大可以繁殖时,它会调用水族馆的繁殖方法。水族馆会将鱼添加到列表中,如果列表中至少有两条鱼,则删除它们,并创建一条新鱼。 (可能有更好的方法来实现这一点,但它会起作用。)
我还建议将
new ArrayList<>();
更改为 Collections.synchronizedList(new ArrayList<>())
。