-
Notifications
You must be signed in to change notification settings - Fork 23
Lab 02 #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Lab 02 #40
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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) { | ||
| 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); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| 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
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
| } | ||
| } | ||
|
|
||
| } | ||
| } | ||
| 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"); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| rootObject = gson.fromJson(reader, RootObject.class); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Зачем |
||
| } 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(); | ||
| } | ||
|
|
||
| } | ||
| } | ||
| 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); | ||
| } | ||
| } |
| 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(); | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут тогда лучше переписать на синхронизацию по
good.