Skip to content
Open

Lab2 #32

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
3 changes: 3 additions & 0 deletions lab-02/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.idea/
/lab-02.iml
/out/
Binary file added lab-02/lib/json-simple-1.1.jar
Binary file not shown.
24 changes: 24 additions & 0 deletions lab-02/src/by/parfen01/docks_and_hobos/CargoDecoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package by.parfen01.docks_and_hobos;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.stream.IntStream;

public class CargoDecoder {
private final HashMap<String, Integer> cargoRepresent;
private final ArrayList<String> productNames;

public CargoDecoder(ArrayList<String> cargo) {
this.productNames = cargo;
this.cargoRepresent = new HashMap<>();
IntStream.range(0, cargo.size()).forEach(i -> cargoRepresent.put(cargo.get(i), i));
}

public int cargoToProduct(String cargo) {
return cargoRepresent.get(cargo);
}

public String getProductName(int product) {
return productNames.get(product);
}
}
55 changes: 55 additions & 0 deletions lab-02/src/by/parfen01/docks_and_hobos/Dock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package by.parfen01.docks_and_hobos;

import by.parfen01.docks_and_hobos.control.Controller;
import by.parfen01.docks_and_hobos.ships.Ship;

import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.logging.Level;

import static java.lang.Thread.sleep;

public class Dock {
private final int id;
private final int unloadingSpeed;
private final int[] maxProductCapacity;
private final AtomicIntegerArray productsCount;

public Dock(int id, int unloadingSpeed, int[] maxProductCapacity) {
this.id = id;
this.unloadingSpeed = unloadingSpeed;
this.maxProductCapacity = maxProductCapacity;
productsCount = new AtomicIntegerArray(maxProductCapacity.length);
}

public void UnloadShip(Ship ship) throws InterruptedException {
Controller.getController().getConsoleLogger().log(
Level.INFO, "Ship number " + ship.getId() + " started to unload in dock number " + id);
int product = Controller.getController().getCargoDecoder().cargoToProduct(ship.getCargoType());
int pred = productsCount.get(product);
productsCount.set(product, Math.min(maxProductCapacity[product],
productsCount.get(product) + ship.getShipCapacity()));
sleep((productsCount.get(product) - pred) * 1000L / unloadingSpeed);
Comment on lines +29 to +31
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.

Тут надо сохранять и использовать локальные перменные, ибо за это время могу придти и стырить и тогда получим неверное время ожидание.

Controller.getController().getConsoleLogger().log(
Level.INFO, "Ship number " + ship.getId() + " unloaded in dock number " + id);
}

public void start() throws InterruptedException {
Controller.getController().getConsoleLogger().log(
Level.INFO, "Dock number " + id + " started to work");
while (Controller.getController().isWorking()) {
UnloadShip(Controller.getController().getTunnel().getShip());
}
}

public boolean stealProduct(int product) {
if (productsCount.get(product) == 0) {
return false;
}
productsCount.decrementAndGet(product);
Comment on lines +45 to +48
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.

Тут все может поменяться:
Пусть у нас 1 еденица товара:

  1. Проверяем на 0, 1 != 0.
  2. Вклинивается другой пототок, проверяем на 0 и забирает товар.
  3. Просыпается первый и забирает товар, в итоге ушли в минус.

return true;
}

public int getId() {
return id;
}
}
26 changes: 26 additions & 0 deletions lab-02/src/by/parfen01/docks_and_hobos/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package by.parfen01.docks_and_hobos;

import by.parfen01.docks_and_hobos.control.Controller;
import by.parfen01.docks_and_hobos.control.ProjectInitializer;
import org.json.simple.parser.ParseException;

import java.io.IOException;

import static java.lang.Thread.sleep;

public class Main {
public static void main(String[] args) throws InterruptedException, IOException, ParseException {
if (args.length != 1) {
throw new IllegalArgumentException("wrong number of arguments");
}
String path = args[0];
Controller controller = ProjectInitializer.initController(path);
controller.start();
sleep(10 * 1000L);
controller.stop();
sleep(10 * 1000L);
controller.start();
sleep((500 * 1000L));
controller.stop();
}
}
40 changes: 40 additions & 0 deletions lab-02/src/by/parfen01/docks_and_hobos/Tunnel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package by.parfen01.docks_and_hobos;

import by.parfen01.docks_and_hobos.control.Controller;
import by.parfen01.docks_and_hobos.ships.Ship;

import java.util.ArrayDeque;
import java.util.logging.Level;

public class Tunnel {
private final ArrayDeque<Ship> shipQueue;
private final int maxShipCount;

public Tunnel(int maxShipCount) {
this.maxShipCount = maxShipCount;
this.shipQueue = new ArrayDeque<>();
}

public synchronized void addShip(Ship ship) {
if (shipQueue.size() == maxShipCount) {
Controller.getController().getConsoleLogger().log(
Level.INFO, "The ship number " + ship.getId() + " sank");
return;
}
shipQueue.add(ship);
notify();
Controller.getController().getConsoleLogger().log(
Level.INFO, "The ship number " + ship.getId() + " entered tunnel");
}

public synchronized Ship getShip() throws InterruptedException {
while (shipQueue.isEmpty()) {
wait();
}
Ship result = shipQueue.poll();
assert(result != null);
Controller.getController().getConsoleLogger().log(
Level.INFO, "The ship number " + result.getId() + " leaved tunnel");
return result;
}
}
71 changes: 71 additions & 0 deletions lab-02/src/by/parfen01/docks_and_hobos/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"ShipGenerator" : {
"shipCapacityMin" : 1,
"shipCapacityMax" : 100,
"generatingTime" : 10,
"cargoTypes" : [
"milk",
"meat",
"bread",
"carrot",
"cucumber"
]
},
"Tunnel" : 7,
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.

Тут тоже непонятно, что это за константа.

"Docks" : [
{
"id" : 1,
"unloadingSpeed" : 4,
"maxProductCapacity" : [
50,
50,
20,
25,
100
]
},
{
"id" : 2,
"unloadingSpeed" : 7,
"maxProductCapacity" : [
80,
100,
35,
40,
55
]
}
],
"Hobos" : [
{
"stealingTime" : 7,
"name" : "Ivan"
},
{
"stealingTime" : 2,
"name" : "Vlad"
},
{
"stealingTime" : 1,
"name" : "Danil"
},
{
"stealingTime" : 5,
"name" : "Nicolay"
},
{
"stealingTime" : 3,
"name" : "Jon"
}
],
"hobosVillage" : {
"eatingTime" : 10,
"ingredientsCount" : [
11,
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.

Я бы мап сделал, так наугад не совсем понятно.

4,
8,
9,
2
]
}
}
114 changes: 114 additions & 0 deletions lab-02/src/by/parfen01/docks_and_hobos/control/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package by.parfen01.docks_and_hobos.control;

import by.parfen01.docks_and_hobos.CargoDecoder;
import by.parfen01.docks_and_hobos.Dock;
import by.parfen01.docks_and_hobos.Tunnel;
import by.parfen01.docks_and_hobos.hobos.HobosVillage;
import by.parfen01.docks_and_hobos.ships.ShipGenerator;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Controller {
private boolean isWorking;
private final ShipGenerator shipGenerator;
private final HobosVillage hobosVillage;
private final Tunnel tunnel;
private final CargoDecoder cargoDecoder;
private final ArrayList<Dock> docks;
private ArrayList<Thread> workingThreads;
private final Logger consoleLogger;
private static Controller controller;

public Controller(ShipGenerator shipGenerator,
HobosVillage hobosVillage, Tunnel tunnel,
CargoDecoder cargoDecoder, ArrayList<Dock> docks) {
this.isWorking = false;
this.shipGenerator = shipGenerator;
this.hobosVillage = hobosVillage;
this.tunnel = tunnel;
this.cargoDecoder = cargoDecoder;
this.docks = docks;
this.consoleLogger = Logger.getLogger(Controller.class.getName());
controller = this;
}

public static Controller getController() {
return controller;
}

public HobosVillage getHobosVillage() {
return hobosVillage;
}

public Tunnel getTunnel() {
return tunnel;
}

public CargoDecoder getCargoDecoder() {
return cargoDecoder;
}

public ArrayList<Dock> getDocks() {
return docks;
}

public Logger getConsoleLogger() {
return consoleLogger;
}

public boolean isWorking() {
return isWorking;
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.

У нас же тут гонка? Ты вызываешь isWorking из разных потоков, а еще можешь вызвать либо start либо stop.

}

public void start() {
isWorking = true;
consoleLogger.log(
Level.INFO, "Start");
workingThreads = new ArrayList<>();
Thread shipGeneratorThread = new Thread(() -> {
try {
shipGenerator.start();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
workingThreads.add(shipGeneratorThread);
Thread hobosVillageThread = new Thread(() -> {
try {
hobosVillage.start();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
workingThreads.add(hobosVillageThread);
for (Dock i : docks) {
Thread dockThread = new Thread(() -> {
try {
i.start();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
workingThreads.add(dockThread);
}
for (Thread i : workingThreads) {
i.start();
}
}

public void stop() throws InterruptedException {
if (workingThreads == null) {
return;
}
isWorking = false;
for (Thread i : workingThreads) {
if (i.getState() != Thread.State.WAITING) {
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.

Тут же не все поджойнились.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Так суть в том, что мы не джойним тех, кто вэйтит, ибо это бесконечное ожидание

i.join();
}
}
consoleLogger.log(
Level.INFO, "Stop");
}
}
Loading