Как указать потокам работать по очереди в цикле
У меня есть такие потоки. Factory производит детали(10 в день), а Factions их забирает(рандомно 5 штук в день). По моей задаче сначала отрабатывает Factory, потом Factions, потом снова Factory и так по кругу(число итераций может быть любое). Вот только я не понимаю, где именно надо это прописывать. В потоках ли это прописывать или в классах, которые вызывают эти потоки... Если что то непонятно объяснил, извиняюсь, так как сам в ступоре.
public class FactionsThread implements Runnable {
private final int DAYS = 10;
private final Factions factions;
public FactionsThread(Factions factions) {
this.factions = factions;
}
@Override
public void run() {
factions.getPartsFromFactory(); //вызывает метод из класса Factions, который забирает детали из Factory;
factions.printAmountsPart();
}
}
public class FactoryProduceThread implements Runnable {
private final int DAYS = 10;
private final Factory factory;
public FactoryProduceThread(Factory factory) {
this.factory = factory;
}
@Override
public void run() {
System.out.println("Start producing");
factory.produceParts(); //вызывает метод из класса Factory, который производит детали.
factory.printFactoryDayResult();
System.out.println("End producing");
}
public class Factory {
private static final Random random = new Random();
private int head = 0;
private int torso = 0;
private int hand = 0;
private int feet = 0;
public void produceParts() {
final int PARTS_EACH_DAY = 10;
for (int i = 0; i < PARTS_EACH_DAY; i ++) {
switch (random.nextInt(4)) {
case 0:
head++;
break;
case 1:
torso++;
break;
case 2:
hand++;
break;
case 3:
feet++;
break;
}
}
}
public void printFactoryDayResult() {
System.out.println("---Factory producing day result---\n Heads: " + head
+ " Torso: " + torso
+ " Hands: " + hand
+ " Feet: " + feet);
}
public boolean pickUpHead() {
if (head > 0) {
head--;
return true;
}
return false;
}
public boolean pickUpTorso() {
if (torso > 0) {
torso--;
return true;
}
return false;
}
public boolean pickUpHand() {
if (hand > 0) {
hand--;
return true;
}
return false;
}
public boolean pickUpFeet() {
if (feet > 0) {
feet--;
return true;
}
return false;
}
public class Factions {
private final Random random = new Random();
private final Factory factory;
private int head = 0;
private int torso = 0;
private int hand = 0;
private int feet = 0;
public Factions(Factory factory) {
this.factory = factory;
}
public void getPartsFromFactory() {
final int MAX_GETTING_PARTS_EACH_DAYS = 5;
for (int i = 0; i < MAX_GETTING_PARTS_EACH_DAYS; i++) {
switch (random.nextInt(4)) {
case 0:
if (factory.pickUpHead()) {
head++;
}
break;
case 1:
if (factory.pickUpTorso()) {
torso++;
}
break;
case 2:
if (factory.pickUpHand()) {
hand++;
}
break;
case 3:
if (factory.pickUpFeet()) {
feet++;
}
break;
}
}
}
public void printAmountsPart() {
System.out.println("---" + Thread.currentThread().getName() + "---\n Amount heads: " + head
+ " Amount torso: " + torso
+ " Amount hands: " + hand
+ " Amount feet: " + feet);
}
Ответы (1 шт):
Переписал код таким образом. Создал общий склад куда обращаются Faction и Factory. Создал в Storage переменную isDay, что бы указывать, когда поток должен засыпать. И при помощи wait() отправлял в сон потоки по очереди. Код не финальный, но идею реализовал.
public class Factions {
private final Storage storage;
private final String head = "head";
private final String torso = "torso";
private final String hand = "hand";
private final String feet = "feet";
private Map<String, Integer> partsList = new HashMap<>(Map.of(
head, 0,
torso, 0,
hand, 0,
feet, 0
));
public Factions(Storage storage) {
this.storage = storage;
}
public void getPartsFromStorage() {
partsList = storage.getPartsToFactions();
}
public void printAmountsPart() {
System.out.println("---" + Thread.currentThread().getName() + "---\n " + partsList.toString());
}
}
public class Factory {
Storage storage;
public Factory(Storage storage) {
this.storage = storage;
}
public synchronized void factoryStartWork() {
storage.produceParts();
}
}
public class Storage {
public boolean isDay = true;
Random random = new Random();
private final String head = "head";
private final String torso = "torso";
private final String hand = "hand";
private final String feet = "feet";
private Map<String, Integer> partsList = new HashMap<>(Map.of(
head, 0,
torso, 0,
hand, 0,
feet, 0
));
public synchronized void produceParts() {
while (!isDay) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
final int PARTS_EACH_DAY = 10;
for (int i = 0; i < PARTS_EACH_DAY; i++) {
switch (random.nextInt(4)) {
case 0:
partsList.put(head, partsList.get(head) + 1);
break;
case 1:
partsList.put(torso, partsList.get(torso) + 1);
break;
case 2:
partsList.put(hand, partsList.get(hand) + 1);
break;
case 3:
partsList.put(feet, partsList.get(feet) + 1);
break;
}
}
setDay(false);
notifyAll();
}
public synchronized Map<String, Integer> getPartsToFactions() {
while (isDay) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Map<String, Integer> partsListForFactions = new HashMap<>(Map.of(
head, 0,
torso, 0,
hand, 0,
feet, 0
));
final int PARTS_EACH_DAY = 5;
for (int i = 0; i < PARTS_EACH_DAY; i++) {
switch (random.nextInt(4)) {
case 0:
if (partsList.get(head) > 0) {
partsList.replace(head, partsList.get(head) - 1);
partsListForFactions.put(head, partsListForFactions.get(head) + 1);
}
break;
case 1:
if (partsList.get(torso) > 0) {
partsList.replace(torso, partsList.get(torso) - 1);
partsListForFactions.put(torso, partsListForFactions.get(torso) + 1);
}
break;
case 2:
if (partsList.get(hand) > 0) {
partsList.replace(hand, partsList.get(hand) - 1);
partsListForFactions.put(hand, partsListForFactions.get(hand) + 1);
}
break;
case 3:
if (partsList.get(feet) > 0) {
partsList.replace(feet, partsList.get(feet) - 1);
partsListForFactions.put(feet, partsListForFactions.get(feet) + 1);
}
break;
}
}
setDay(true);
notifyAll();
return partsListForFactions;
}
public void printFactoryDayResult() {
System.out.println("---Factory producing day result---\n " + partsList.toString());
}
public void setDay(boolean day) {
isDay = day;
}
}
public class FactionsThread implements Runnable {
private final Factions factions;
public FactionsThread(Factions factions) {
this.factions = factions;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
factions.getPartsFromStorage();
factions.printAmountsPart();
}
}
}
public class FactoryProduceThread implements Runnable {
private final Factory factory;
private final Storage storage;
public FactoryProduceThread(Factory factory, Storage storage) {
this.factory = factory;
this.storage = storage;
}
@Override
public void run() {
for (int i = 0; i <= 10; i++) {
factory.factoryStartWork();
storage.printFactoryDayResult();
}
}
}