Skip to content
Open

Lab2 #35

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
12 changes: 12 additions & 0 deletions lab-02/DocksAndHobos/DocksAndHobos.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="json-simple-1.1" level="project" />
</component>
</module>
22 changes: 22 additions & 0 deletions lab-02/DocksAndHobos/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"generating_time": 15,
"ship_capacity_min": 20,
"ship_capacity_max": 100,
"max_ships": 4,
"unloading_speed": 7,
"dock_capacity": 100,
"hobos": 10,
"stealing_time": 2,
"eating_time": 3,
"cargo_types" : [
"meat",
"fish",
"oil"
],

"ingredients_count" : [
7,
2,
10
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package by.DaniilDomnin.doks_and_hobos;

import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Controller {
Controller(ShipGenerator generator, Docks docks, long generating_time, long max_ships) throws InterruptedException {
this.generator = generator;
this.generating_time = generating_time;
this.max_ships = max_ships;
this.docks = docks;
ship_count = new AtomicInteger();
consoleLOgger = Logger.getLogger(" ");
Thread thread = new Thread(docks::StartStealing);
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.

Не стоит делать такое в конструкторе.

thread.start();
Generating();
}

private void Generating() throws InterruptedException {
while (true) {
if (ship_count.get() < max_ships) {
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.

Миссматч типов.

Ship ship = generator.GenerateShip();
consoleLOgger.log(Level.INFO, "Generate new ship");
Thread thread = new Thread(()->{
try {
Uploading(ship);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
thread.start();
ship_count.incrementAndGet();
Comment on lines +24 to +35
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.

Между этими строчками можем произойти множество событий и кораблей сюда зайдет намного больше чем max_ship и ship_count может даже в минус уйти. И не хорошо оставлять висеть потоки.

} else {
consoleLOgger.log(Level.INFO, "The ship sank in the tunnel");
}

Thread.sleep(generating_time * 1000);
}
}

private void Uploading(Ship ship) throws InterruptedException {
docks.Unloading(ship);
ship_count.decrementAndGet();
}

public static Logger GetConsoleLogger () {
return consoleLOgger;
}

private final ShipGenerator generator;

private static Logger consoleLOgger;

private final AtomicInteger ship_count;
private final long generating_time;

private final long max_ships;

private final Docks docks;
}
125 changes: 125 additions & 0 deletions lab-02/DocksAndHobos/src/by/DaniilDomnin/doks_and_hobos/Docks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package by.DaniilDomnin.doks_and_hobos;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;

public class Docks {
Docks(long dock_capacity, long unloading_speed, ArrayList<String> cargo_names, long hobos, ArrayList<Long> ingredients_count, long eating_time, long stealing_time) {
this.dock_capacity = dock_capacity;
this.unloading_speed = unloading_speed;
this.hobos = hobos;
this.ingredients_count = ingredients_count;
this.eating_time = eating_time;
this.stealing_time = stealing_time;
this.cargo_names = cargo_names;
current_ingredients_count = new ArrayList<>();
for (int i = 0; i < ingredients_count.size(); ++i) {
current_ingredients_count.add(0L);
}
add_ingredient_mutex = new ReentrantLock();
cargo_names.forEach(x -> {
cargo_count.put(x, 0L);
});

}

public void Unloading (Ship ship) throws InterruptedException {
long capacity = ship.GetCapacity();
while (ship.GetCapacity() != 0) {
Thread.sleep(1000);
cargo_count.put(ship.GetCargoName(), Math.min(cargo_count.get(ship.GetCargoName()) + Math.min(ship.GetCapacity(), unloading_speed), dock_capacity));
ship.SetCapacity(Math.max(0, ship.GetCapacity() - unloading_speed));
}
Controller.GetConsoleLogger().log(Level.INFO, "Unload " + capacity + " " + ship.GetCargoName());
}

public void StartStealing () {
for (int i = 0; i < hobos - 2; ++i) {
Thread thread = new Thread(() -> {
try {
Stealing();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
thread.start();
}
}

private void Stealing () throws InterruptedException {
while (true) {
Thread.sleep(stealing_time * 1000);
add_ingredient_mutex.lock();
int index = GetStealIndex();
if (index == -1) {
continue;
}
Controller.GetConsoleLogger().log(Level.INFO, "Hobo steals " + cargo_names.get(index));
cargo_count.put(cargo_names.get(index), cargo_count.get(cargo_names.get(index)) - 1);
current_ingredients_count.set(index, current_ingredients_count.get(index) + 1);
if (CanStartEating()) {
ClearCurrentIngredients();
Controller.GetConsoleLogger().log(Level.INFO, "Hobos start eating");
Thread.sleep(eating_time * 1000);
Controller.GetConsoleLogger().log(Level.INFO, "Hobos finish eating");
}
add_ingredient_mutex.unlock();
}
}

private int GetStealIndex () {
ArrayList<Integer> indexes = new ArrayList<Integer>();
for (int i = 0; i < cargo_names.size(); ++i) {
if (cargo_count.get(cargo_names.get(i)) > 0) {
indexes.add(i);
}
}
if (indexes.size() == 0) {
return -1;
}
return indexes.get(new Random().nextInt(0, indexes.size()));
}

private void ClearCurrentIngredients() {
for (int i = 0; i < current_ingredients_count.size(); ++i) {
current_ingredients_count.set(i, current_ingredients_count.get(i) - ingredients_count.get(i));
}
}

private boolean CanStartEating () {
for (int i = 0; i < current_ingredients_count.size(); ++i) {
if (current_ingredients_count.get(i) < ingredients_count.get(i)) {
return false;
}
}
return true;
}




private final long dock_capacity;
private final long unloading_speed;

private final long hobos;

private final long eating_time;

private final long stealing_time;

private final ArrayList<Long> current_ingredients_count;

private final Lock add_ingredient_mutex;

private final ArrayList<Long> ingredients_count;

private final ArrayList<String> cargo_names;

private final ConcurrentHashMap<String, Long> cargo_count = new ConcurrentHashMap<>();
}
24 changes: 24 additions & 0 deletions lab-02/DocksAndHobos/src/by/DaniilDomnin/doks_and_hobos/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package by.DaniilDomnin.doks_and_hobos;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class Main {

public static void main(String[] args) throws IOException, ParseException, InterruptedException {
Object obj = new JSONParser().parse(new FileReader(args[0]));
JSONObject jo = (JSONObject) obj;
ShipGenerator generator = new ShipGenerator((long)jo.get("ship_capacity_max"), (long)jo.get("ship_capacity_min"), (ArrayList<String>) jo.get("cargo_types"));
Docks docks = new Docks((long)jo.get("dock_capacity"), (long)jo.get("unloading_speed"), (ArrayList<String>) jo.get("cargo_types"), (long)jo.get("hobos"), (ArrayList<Long>) jo.get("ingredients_count"), (long)jo.get("eating_time"), (long)jo.get("stealing_time"));
Controller c = new Controller(generator, docks, (long)jo.get("generating_time"), (long)jo.get("max_ships"));
}
}
23 changes: 23 additions & 0 deletions lab-02/DocksAndHobos/src/by/DaniilDomnin/doks_and_hobos/Ship.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package by.DaniilDomnin.doks_and_hobos;

public class Ship {
Ship(long capacity, String cargo_name) {
this.capacity = capacity;
this.cargo_name= cargo_name;
}

public String GetCargoName () {
return cargo_name;
}

public long GetCapacity () {
return capacity;
}

public void SetCapacity (long capacity) {
this.capacity = capacity;
}

private long capacity;
private final String cargo_name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package by.DaniilDomnin.doks_and_hobos;

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

public class ShipGenerator {

ShipGenerator(long ship_capacity_max, long ship_capacity_min, ArrayList<String> cargo_names) {
this.ship_capacity_max = ship_capacity_max;
this.ship_capacity_min = ship_capacity_min;
this.cargo_names = cargo_names;
}

public Ship GenerateShip() {
Random ran = new Random();
return new Ship(ran.nextLong(ship_capacity_min, ship_capacity_max + 1), cargo_names.get(ran.nextInt(0, cargo_names.size())));
}

private long ship_capacity_max;
private long ship_capacity_min;

private ArrayList<String> cargo_names;
}
43 changes: 0 additions & 43 deletions lab-02/README.md

This file was deleted.