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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea/
out/
Binary file added lab-02/gson-2.10.1.jar
Binary file not shown.
67 changes: 67 additions & 0 deletions lab-02/src/by/BelArtem/docks_and_hobos/Dock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package by.BelArtem.docks_and_hobos;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicIntegerArray;

public class Dock implements Runnable{

private final int unloadingSpeed;

private final int dockCapacity;

private final AtomicIntegerArray stock;

private final TunnelManager tunnelManager;

private final ArrayList<String> cargo_types;

public Dock(int unloadingSpeed, int dockCapacity,
TunnelManager tunnelManager, ArrayList<String> cargo_types) {

this.unloadingSpeed = unloadingSpeed;
this.dockCapacity = dockCapacity;
stock = new AtomicIntegerArray(cargo_types.size());
this.tunnelManager = tunnelManager;
this.cargo_types = cargo_types;
}

public AtomicIntegerArray getStock() {
return stock;
}

@Override
public void run() {
while(true) {
Ship ship = tunnelManager.getFirstShip();
if (ship == null) {
continue;
}
System.out.println("New ship info: ");
System.out.println("Cargo: " + ship.getCargoType() +
"; capacity: " + ship.getCapacity());
String cargoType = ship.getCargoType();
int index = cargo_types.indexOf(cargoType);
while (ship.getCargoLeft() != 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}

int itemsToPut = Math.min(ship.getCargoLeft(), this.unloadingSpeed);
this.stock.set(index, Math.min(this.dockCapacity,
this.stock.get(index) + itemsToPut));

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.

тут гонка с действиями в hobos.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Не совсем понимаю, при каких условиях тут может возникнуть проблема

ship.unloadShip(itemsToPut);
System.out.println("Ship info: " + ship.getCargoLeft() + " cargo left");
System.out.println("The dock " + Thread.currentThread().getName() + " info:");
for (int i = 0; i < cargo_types.size(); ++i) {
System.out.println(this.stock.get(i));
}
System.out.println("End of info\n");
}
System.out.println("===========================");

}

}
}
23 changes: 23 additions & 0 deletions lab-02/src/by/BelArtem/docks_and_hobos/DocksManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package by.BelArtem.docks_and_hobos;

import java.util.ArrayList;
import java.util.List;

public class DocksManager implements Runnable{

private final List<Dock> dockList;

public DocksManager(List<Dock> dockList) {
this.dockList = dockList;
}

@Override
public void run() {
ArrayList<Thread> threads = new ArrayList<>();
int size = dockList.size();
for (int i = 0; i < size; ++i) {
threads.add(new Thread(dockList.get(i)));
threads.get(i).start();
}
}
}
98 changes: 98 additions & 0 deletions lab-02/src/by/BelArtem/docks_and_hobos/Hobo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package by.BelArtem.docks_and_hobos;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicIntegerArray;

public class Hobo implements Runnable{

private final List<Dock> dockList;

private final ArrayList<Integer> indicesOfIngredientsToSteal = new ArrayList<>();

private AtomicIntegerArray necessaryIngredients;

private final int stealingTime;

private boolean isCooking;


public Hobo(List<Dock> docks, AtomicIntegerArray necessaryIngredients, int stealingTime) {
this.dockList = docks;
this.necessaryIngredients = necessaryIngredients;
this.stealingTime = stealingTime;
this.isCooking = false;
}

public boolean getCookingState() {
return this.isCooking;
}

public void setCookingState(boolean newState) {
this.isCooking = newState;
}


public void addIngredient(int index) {
indicesOfIngredientsToSteal.add(index);
}

public void setNecessaryIngredients (AtomicIntegerArray necessaryIngredients) {
this.necessaryIngredients = necessaryIngredients;
}

@Override
public void run() {
if (!this.isCooking) {
for (int ingredientIndex : indicesOfIngredientsToSteal) {
steelIngredient(ingredientIndex);
}
return;
}
while (!this.areAllIngredientsCollected()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Error happened while attempting to sleep");
throw new RuntimeException(e);
}
}
}

private void steelIngredient(int index) {
Random random = new Random();
while (necessaryIngredients.get(index) > 0) {
int randomDockIndex = random.nextInt(dockList.size());
AtomicIntegerArray currentStock = dockList.get(randomDockIndex).getStock();
while (necessaryIngredients.get(index) > 0 && currentStock.get(index) > 0){
int itemsLeft = currentStock.decrementAndGet(index);
Comment on lines +68 to +69

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.

Между этими двумя стрчоками может произойти событие и тогда currentStock.get(index) == 0 и после этого уйдет в минус.

if (itemsLeft < 0){
currentStock.incrementAndGet(index);
break;
}
Comment on lines +70 to +73

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.

Это не совсем поможет исправить ситуацию, надо делать через CAS.


try {
Thread.sleep(this.stealingTime * 1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + " Has stolen a " + index + " item");

necessaryIngredients.set(index, Math.max( 0, necessaryIngredients.get(index) - 1));
}
}
}

private boolean areAllIngredientsCollected() {
boolean result = true;
int size = necessaryIngredients.length();
for (int i = 0; i < size; ++i) {
if (necessaryIngredients.get(i) != 0) {
result = false;
break;
}
}
return result;
}
}
113 changes: 113 additions & 0 deletions lab-02/src/by/BelArtem/docks_and_hobos/HobosManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package by.BelArtem.docks_and_hobos;

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.atomic.AtomicIntegerArray;

public class HobosManager implements Runnable{

private final ArrayList<Hobo> hobos;

private final int eatingTime;

private ArrayList<Hobo> workingHobos;

private final AtomicIntegerArray ingredients;

public HobosManager(ArrayList<Hobo> hobos, int eatingTime,
AtomicIntegerArray ingredients) {
this.hobos = hobos;
this.eatingTime = eatingTime;
this.ingredients = ingredients;
}

@Override
public void run() {
while (true) {
System.out.println("Hobos are starting stealing");
AtomicIntegerArray necessaryIngredients = new AtomicIntegerArray(ingredients.length());
for (int i = 0; i < necessaryIngredients.length(); ++i) {
necessaryIngredients.set(i, ingredients.get(i));
}
for (Hobo hobo: hobos) {
hobo.setNecessaryIngredients(necessaryIngredients);
}

this.distributeResponsibilities();
this.createStrategy();

ArrayList<Thread> threads = new ArrayList<>();

int size = hobos.size();
for (int i = 0; i < size; ++i) {
threads.add(new Thread(hobos.get(i)));
threads.get(i).start();
}
for (int i = 0; i < size; ++i) {
try {
threads.get(i).join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

System.out.println("Hobos are about to eat");
try {
Thread.sleep(eatingTime * 1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

}

private void distributeResponsibilities() {
for (Hobo hobo: this.hobos) {
hobo.setCookingState(false);
}

workingHobos = new ArrayList<>(hobos);

Random random = new Random();
for (int i = 0; i < 2; ++i) {
int randIndex = random.nextInt(workingHobos.size());
workingHobos.get(randIndex).setCookingState(true);
workingHobos.remove(randIndex);
}

}

private void createStrategy() {
int workingHobosNumber = this.workingHobos.size();
int ingredientsNumber = this.ingredients.length();

if (workingHobosNumber > ingredientsNumber) {
int cyclesCount = workingHobosNumber / ingredientsNumber;
for (int i = 0; i < cyclesCount; ++i) {
for (int j = 0; j < ingredientsNumber; ++j) {
this.workingHobos.get(i * ingredientsNumber + j).addIngredient(j);
}
}

int freeHobosLeft = workingHobosNumber - cyclesCount * ingredientsNumber;
int startIndex = cyclesCount * ingredientsNumber;
for (int i = 0; i < freeHobosLeft; ++i) {
this.workingHobos.get(startIndex + i).addIngredient(i);
}
return;
}

int cyclesCount = ingredientsNumber / workingHobosNumber;
for (int i = 0; i < cyclesCount; ++i) {
for (int j = 0; j < workingHobosNumber; ++j) {
this.workingHobos.get(j).addIngredient(i * workingHobosNumber + j);
}
}

int ingredientLeft = ingredientsNumber - cyclesCount * workingHobosNumber;
int startIndex = cyclesCount * workingHobosNumber;
for (int i = 0; i < ingredientLeft; ++i) {
this.workingHobos.get(i).addIngredient(startIndex + i);
}
}
}
9 changes: 9 additions & 0 deletions lab-02/src/by/BelArtem/docks_and_hobos/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package by.BelArtem.docks_and_hobos;

public class Main {

public static void main(String[] args) throws InterruptedException {
Program program = new Program();
program.start();
}
}
Loading