Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions lab-02/by/mnik0_0/docks_and_hobos/Dock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package by.mnik0_0.docks_and_hobos;

import java.util.ArrayList;
import java.util.HashMap;
import static java.lang.Math.min;

public class Dock implements Runnable {
private final int unloadingSpeed;
private final int dockCapacity;
private final HashMap<String, Integer> goods = new HashMap<>();
private Tunnel tunnel;
private String name;

public String getName() {
return name;
}

public Dock(int unloadingSpeed, int dockCapacity, Tunnel tunnel, String name, ArrayList<String> types) {
this.unloadingSpeed = unloadingSpeed;
this.dockCapacity = dockCapacity;
this.tunnel = tunnel;
this.name = name;
for (String type: types) {
goods.put(type, 0);
}
}

public int getUnloadingSpeed() {
return unloadingSpeed;
}

public int getDockCapacity() {
return dockCapacity;
}

public synchronized boolean getGoodByType(String type) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут тогда лучше переписать на синхронизацию по good.

int count = goods.get(type);
if (count == 0) {
return false;
}
goods.put(type, count - 1);
return true;
}

@Override
public void run() {
while (true) {
Ship ship = tunnel.getShipFromTunnel(this);

if (ship == null) {
continue;
}

double timeInSeconds = ship.getCapacity() / (double) unloadingSpeed;
try {
Thread.sleep((long) (timeInSeconds * 1000L));
} catch (InterruptedException e) {
e.printStackTrace();
}

int capacity = ship.getCapacity();
String type = ship.getCargoType();
synchronized (goods) {
int capacityInDocks = goods.get(type);
int tmpResult = capacityInDocks + capacity;
int result = min(tmpResult, dockCapacity);
int delta = tmpResult - result;
if (delta > 0) {
System.out.printf("We lose in %s - %s %d%n", name, type, delta);
}
goods.put(type, result);

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("------------------------\n");
stringBuilder.append(name).append("\n");
for (String t: goods.keySet()) {
stringBuilder.append(t).append(" ").append(goods.get(t)).append("\n");
}
stringBuilder.append("------------------------\n");
System.out.println(stringBuilder);
}
}
}
}
102 changes: 102 additions & 0 deletions lab-02/by/mnik0_0/docks_and_hobos/HoboGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package by.mnik0_0.docks_and_hobos;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

public class HoboGroup implements Runnable {
private HashMap<String, Integer> ingredientsCount;
private HashMap<String, Integer> ingredientsWeNeed;
private ArrayList<String> types = new ArrayList<>();
private int hobos;
private final Dock dock;
private Random random = new Random();
int stealingTime;
int eatingTime;
int startIndex;

public HoboGroup(HashMap<String, Integer> ingredientsCount, int hobos, Dock dock, int stealingTime, int eatingTime) {
this.ingredientsCount = ingredientsCount;
this.hobos = hobos;
this.dock = dock;
this.ingredientsWeNeed = new HashMap<>(ingredientsCount);
this.types.addAll(ingredientsCount.keySet());
this.stealingTime = stealingTime;
this.eatingTime = eatingTime;
}

public String getTypeToSteal() {
int currentIndex = startIndex;
startIndex = (startIndex + 1) % types.size();
int counter = 0;

while (counter < types.size()) {
String type = types.get(currentIndex);
int count = ingredientsWeNeed.get(type);
if (count != 0) {
ingredientsWeNeed.put(type, count - 1);
return type;
}
counter++;
currentIndex = (currentIndex + 1) % types.size();
}

return null;
}

public boolean readyToCook() {
for (int counter : ingredientsWeNeed.values()) {
if (counter != 0) {
return false;
}
}
return true;
}

@Override
public void run() {

while (true) {

int workers = hobos - 2;

for (int i = 0; i < workers; i++) {
String type = getTypeToSteal();
if (type == null) {
continue;
}
if (!dock.getGoodByType(type)) {

int count = ingredientsWeNeed.get(type);
ingredientsWeNeed.put(type, count + 1);
}
}
Comment on lines +62 to +73

@Rrenkens Rrenkens Dec 28, 2023

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот это должно быть в параллель, а не последовательно.


try {
Thread.sleep(stealingTime * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("------------------------\n");
stringBuilder.append("hobos in ").append(dock.getName()).append("\n");
for (String t: ingredientsWeNeed.keySet()) {
stringBuilder.append(t).append(" ").append(ingredientsWeNeed.get(t)).append("/").append(ingredientsCount.get(t)).append("\n");
}
stringBuilder.append("------------------------\n");
System.out.println(stringBuilder);

if (readyToCook()) {
System.out.printf("Eating in %s%n", dock.getName());
try {
Thread.sleep(eatingTime * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
ingredientsWeNeed = new HashMap<>(ingredientsCount);
}
}

}
}
129 changes: 129 additions & 0 deletions lab-02/by/mnik0_0/docks_and_hobos/Program.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package by.mnik0_0.docks_and_hobos;

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


class RootObject {
class Tunnel {
@SerializedName("maxShips")
public int maxShips;
}

class ShipGenerator {
@SerializedName("generatingTime")
public int generatingTime;

@SerializedName("shipCapacityMin")
public int shipCapacityMin;

@SerializedName("shipCapacityMax")
public int shipCapacityMax;
}

class Dock {

class HoboGroup {
@SerializedName("hobos")
public int hobos;

@SerializedName("stealingTime")
public int stealingTime;

@SerializedName("eatingTime")
public int eatingTime;

@SerializedName("ingredients")
public HashMap<String, Integer> ingredients;
}

@SerializedName("unloadingSpeed")
public int unloadingSpeed;

@SerializedName("dockCapacity")
public int dockCapacity;

@SerializedName("name")
public String name;

@SerializedName("hoboGroup")
public HoboGroup hoboGroup;
}

@SerializedName("types")
public String[] types;

@SerializedName("tunnel")
public Tunnel tunnel;

@SerializedName("shipGenerator")
public ShipGenerator shipGenerator;

@SerializedName("docks")
public Dock[] docks;
}


public class Program {
public static void main(String[] args) {

Gson gson = new Gson();
RootObject rootObject;
try {
FileReader reader = new FileReader("lab-02/by/mnik0_0/docks_and_hobos/config.json");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все переменные должны задаваться в файле config.json. Путь до этого файла передается аргументов в вашу программу

rootObject = gson.fromJson(reader, RootObject.class);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем json конвертировать в gson?

} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
// TUNNEL
Tunnel tunnel = new Tunnel(rootObject.tunnel.maxShips);

// SHIP GENERATOR
int generatingTime = rootObject.shipGenerator.generatingTime;
int shipCapacityMin = rootObject.shipGenerator.shipCapacityMin;
int shipCapacityMax = rootObject.shipGenerator.shipCapacityMax;
ArrayList<String> cargoTypes = new ArrayList<>(
List.of(rootObject.types)
);

ShipGenerator shipGenerator = new ShipGenerator(generatingTime, shipCapacityMin, shipCapacityMax, cargoTypes, tunnel);

// DOCKS AND GROUPS
ArrayList<Dock> docks = new ArrayList<>();
ArrayList<HoboGroup> hoboGroups = new ArrayList<>();
for (RootObject.Dock d: rootObject.docks) {
int unloadingSpeed = d.unloadingSpeed;
int dockCapacity = d.dockCapacity;
String name = d.name;
Dock dock = new Dock(unloadingSpeed, dockCapacity, tunnel, name, cargoTypes);
docks.add(dock);

HashMap<String, Integer> ingredientsCount = d.hoboGroup.ingredients;
int hobos = d.hoboGroup.hobos;
int stealingTime = d.hoboGroup.stealingTime;
int eatingTime = d.hoboGroup.eatingTime;
HoboGroup group = new HoboGroup(ingredientsCount, hobos, dock, stealingTime, eatingTime);
hoboGroups.add(group);
}

Thread shipGeneratorThread = new Thread(shipGenerator);
shipGeneratorThread.start();

for (Dock dock: docks) {
Thread dockThread = new Thread(dock);
dockThread.start();
}

for (HoboGroup hoboGroup: hoboGroups) {
Thread hoboGroupThread = new Thread(hoboGroup);
hoboGroupThread.start();
}

}
}
29 changes: 29 additions & 0 deletions lab-02/by/mnik0_0/docks_and_hobos/Ship.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package by.mnik0_0.docks_and_hobos;

public class Ship {
private final int capacity;
private final String cargoType;
private String name;

public String getName() {
return name;
}

public Ship(int capacity, String cargoType, String name) {
this.capacity = capacity;
this.cargoType = cargoType;
this.name = name;
}

public int getCapacity() {
return capacity;
}

public String getCargoType() {
return cargoType;
}

public void sink() {
System.out.printf("Ship sunk %s%n", name);
}
}
44 changes: 44 additions & 0 deletions lab-02/by/mnik0_0/docks_and_hobos/ShipGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package by.mnik0_0.docks_and_hobos;

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

public class ShipGenerator implements Runnable {
private int generatingTime;
private int shipCapacityMin;
private int shipCapacityMax;
private Tunnel tunnel;
private final ArrayList<String> cargoTypes;
private final Random random = new Random();

public ShipGenerator(int generatingTime, int shipCapacityMin, int shipCapacityMax, ArrayList<String> cargoTypes, Tunnel tunnel) {
this.generatingTime = generatingTime;
this.shipCapacityMin = shipCapacityMin;
this.shipCapacityMax = shipCapacityMax;
this.cargoTypes = cargoTypes;
this.tunnel = tunnel;
}

@Override
public void run() {
int name = 0;
while (true) {
int capacity = random.nextInt(shipCapacityMax - shipCapacityMin + 1) + shipCapacityMin;

int cargoId = random.nextInt(cargoTypes.size());

Ship ship = new Ship(
capacity,
cargoTypes.get(cargoId),
String.valueOf(name)
);
name++;
tunnel.enterTunnel(ship);
try {
Thread.sleep(generatingTime * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Loading