diff --git a/src/main/java/usherbrooke/ift630/App.java b/src/main/java/usherbrooke/ift630/App.java index e532f49..61677ea 100644 --- a/src/main/java/usherbrooke/ift630/App.java +++ b/src/main/java/usherbrooke/ift630/App.java @@ -9,16 +9,16 @@ import java.util.concurrent.ExecutorService; * Hello world! * */ -public class App -{ +public class App { static private int numStops = 10; static private int numBusses = 10; static private int numStopPerBus = 2; static private int numPassengersPerBus = 2; - static private int numPassengers = 20; - static private int numPassengersPerStop = 2; - static private int numThreads = 5; - static private int timeBetweenStops = 5; + static private int numPassengersPerStop = 5; + static private int numPassengers = numPassengersPerStop * numStops; + static private int numThreads = 1; + static private int timeBetweenStops = 0; + static private int timeEmbark = 0; public static void main(String[] args) { ExecutorService threads = Executors.newFixedThreadPool(numThreads); @@ -30,9 +30,25 @@ public class App Stop s = new Stop(k, numPassengersPerStop); stops.add(s); - threads.submit(s); + //threads.submit(s); } + for (int k = 0; k < numBusses; k++) { + ArrayList s_list = new ArrayList(); + Stop s; + while (s_list.size() < numStopPerBus) { + do { + s = stops.get((int) (Math.random() * numStops)); + } while (s_list.contains(s)); + s_list.add(s); + } + Bus b = new Bus(s_list, k, timeBetweenStops, timeEmbark, numPassengersPerBus); + + busses.add(b); + } + + // TODO put pasengers at stops they can catch their bus + // ie, start and stop in bus path + stop after start for (int k = 0; k < numPassengers; k++) { Stop start, dest; @@ -48,34 +64,22 @@ public class App start.addPassenger(p); } - for (int k = 0; k < numBusses; k++) { - ArrayList s_list = new ArrayList(); - Stop s; - while (s_list.size() < numStopPerBus) { - do { - s = stops.get((int) (Math.random() * numStops)); - } while (s_list.contains(s)); - s_list.add(s); - } - Bus b = new Bus(s_list, k, timeBetweenStops, numPassengersPerBus); - + for (Bus b : busses) { b.printDetails(); - - busses.add(b); - - synchronized (b) { - b.notify(); - } } + // start bus thread // (here so init logs are clean) for (Bus b : busses) { - threads.submit(b); + //threads.submit(b); + b.run(); } + + threads.shutdown(); + try { threads.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); - } catch (InterruptedException e) { - } + } catch (InterruptedException e) {} } } diff --git a/src/main/java/usherbrooke/ift630/Bus.java b/src/main/java/usherbrooke/ift630/Bus.java index 80a32fe..1d3745c 100644 --- a/src/main/java/usherbrooke/ift630/Bus.java +++ b/src/main/java/usherbrooke/ift630/Bus.java @@ -10,82 +10,121 @@ public class Bus extends Thread { private int maxCapacity; private int currentCapacity; private int timeBetweenStops; - private Stop currentStop; + private int timeEmbark; + private Stop nextStop; + + private int timeEmbark() { + return (int) (Math.random() * timeEmbark); + } private int timeBetweenStops() { - return (int) (Math.random() * timeBetweenStops * timeBetweenStops); + return (int) (Math.random() * timeBetweenStops); + } + + private boolean askStop() { + boolean res = false; + for (Passenger p : passengers){ + if (p.getDest() == nextStop) { + res = true; + Logger.getInstance().print(id, "Stop asked"); + break; + } + } + + return res; } private Stop goToNextStop() { - currentStop = stops.remove(0); + // if no reason to stop, skip current stop + do { + try { + nextStop = stops.remove(0); + } catch (IndexOutOfBoundsException e) { + nextStop = null; + } + } while ((getNextStopPassengers().isEmpty() || currentCapacity >= maxCapacity) && askStop()); + try { Thread.sleep(timeBetweenStops() * 1000); } catch (InterruptedException e) { - System.out.println(e.getMessage()); } - return currentStop; + return nextStop; } - // TODO ?? + // TODO what private ArrayList getNextStopPassengers() { ArrayList res = new ArrayList(); - for (Passenger p : passengers) { - Stop next = stops.get(1); - next.getPassengerByDest(stops); - } + if (nextStop != null) + for (Passenger p : passengers) { + if (p.getDest() == nextStop) { + res.add(p); + } + + } return res; } @Override public void run() { - while (currentStop != null) { - embarkPassengers(); + try { + while (nextStop != null) { disembarkPassengers(); + embarkPassengers(); - currentStop = goToNextStop(); + nextStop = goToNextStop(); } + } catch (Exception e) { + Logger.getInstance().print(id, "[BUS] exception: " + e.getMessage()); + } + Logger.getInstance().print(id, "[BUS] exiting!"); } - Bus(ArrayList s, int id, int time, int maxCapacity) { - this.timeBetweenStops = time; + Bus(ArrayList s, int id, int timeStop, int timeEmbark, int maxCapacity) { + this.timeBetweenStops = timeStop; + this.timeEmbark = timeEmbark; this.name = "Bus n°" + id; this.id = id; this.passengers = new ArrayList(); this.stops = s; - this.currentStop = stops.get(0); + this.nextStop = stops.remove(0); this.currentCapacity = 0; this.maxCapacity = maxCapacity; } public synchronized void disembarkPassengers() { - for (Passenger p : passengers) { - Logger.getInstance().print(id, "[BUS] " + p.getName() + " got out of " + name); + synchronized (nextStop.getMutex()) { + for (Passenger p : passengers) { + Logger.getInstance().print(id, "\t[BUS] " + p.getName() + " disembarked " + name); - if (p.getDest() == currentStop) { - p.disembark(); - currentCapacity--; + if (p.getDest() == nextStop) { + p.disembark(); + currentCapacity--; + } } } } public synchronized void embarkPassengers() { - try { - ArrayList list = currentStop.getPassengerByDest(stops); - Logger.getInstance().print(id, "[BUS] hop into " + name + "!"); - if (currentCapacity >= maxCapacity) - throw new OverCapacityException("Over bus capacity."); - for (Passenger p : list) { - passengers.add(p); - currentStop.removePassenger(p); - currentCapacity++; + synchronized (nextStop.getMutex()) { + try { + ArrayList list = nextStop.getPassengerByDest(stops); + Logger.getInstance().print(id, "[BUS] hop into " + name + " at stop " + nextStop.getName() + "!"); + Thread.sleep(timeEmbark() * 1000); + if (currentCapacity >= maxCapacity) + throw new OverCapacityException("Over bus capacity."); + for (Passenger p : list) { + passengers.add(p); + nextStop.removePassenger(p); + currentCapacity++; - Logger.getInstance().print(id, - "[BUS] " + p.getName() + " embarked in " + name + " at " + currentStop.getName()); + Logger.getInstance().print(id, + "\t[BUS] " + p.getName() + " embarked in " + name + " at " + nextStop.getName()); + } + } catch (IndexOutOfBoundsException | OverCapacityException | InterruptedException e) { + Logger.getInstance().print(id, "Exception: " + e.getMessage()); } - } catch (IndexOutOfBoundsException | OverCapacityException e) { - Logger.getInstance().print(id, "ERROR " + e.getMessage()); } } @@ -94,10 +133,10 @@ public class Bus extends Thread { Logger.getInstance().print(id, "\t".repeat(indent) + name); Logger.getInstance().print(id, "\t".repeat(indent) + "time between stops: " + timeBetweenStops); Logger.getInstance().print(id, "\t".repeat(indent) + "max capacity: " + maxCapacity); - Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + currentStop.getName()); - Logger.getInstance().print(id, "\t".repeat(indent) + "stops: " ); - + Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + nextStop.getName()); + Logger.getInstance().print(id, "\t".repeat(indent) + "stops: "); + nextStop.printDetails(indent + 1); for (Stop s : stops) { s.printDetails(indent + 1); } @@ -106,5 +145,4 @@ public class Bus extends Thread { public void printDetails() { printDetails(0); } - } diff --git a/src/main/java/usherbrooke/ift630/Passenger.java b/src/main/java/usherbrooke/ift630/Passenger.java index 19d5e43..332af5a 100644 --- a/src/main/java/usherbrooke/ift630/Passenger.java +++ b/src/main/java/usherbrooke/ift630/Passenger.java @@ -2,10 +2,11 @@ package usherbrooke.ift630; public class Passenger { - private String name; - private int id; - private Stop dest; - private Stop start; + private String name; + private int id; + private int color = -1; + private Stop dest; + private Stop start; Passenger(int id, Stop dest, Stop start) { this.id = id; @@ -30,9 +31,14 @@ public class Passenger { return name; } + public void setName(int color) { + this.color = color; + } + public void printDetails(int indent) { - Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Passenger details " + "---".repeat(3)); - Logger.getInstance().print(id, "\t".repeat(indent) + name + " start: " + start.getName() + " dest: " + dest.getName()); + if (color == -1) color = id; + Logger.getInstance().print(color, "\t".repeat(indent) + "---".repeat(3) + " Passenger details " + "---".repeat(3)); + Logger.getInstance().print(color, "\t".repeat(indent) + name + " start: " + start.getName() + " dest: " + dest.getName()); } public void printDetails() { diff --git a/src/main/java/usherbrooke/ift630/Stop.java b/src/main/java/usherbrooke/ift630/Stop.java index 6baf8b1..7d4ce3e 100644 --- a/src/main/java/usherbrooke/ift630/Stop.java +++ b/src/main/java/usherbrooke/ift630/Stop.java @@ -1,13 +1,17 @@ package usherbrooke.ift630; import java.util.ArrayList; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public class Stop implements Runnable { private String name; private int id; private int maxCapacity; private ArrayList passengers; + private Lock mutex = new ReentrantLock(); + // TODO lock mutex when stop is used @Override public void run() { // xd do nothing for now @@ -63,6 +67,18 @@ public class Stop implements Runnable { return maxCapacity; } + public Lock getMutex() { + return mutex; + } + + public void printDetails(int indent, int color) { + Logger.getInstance().print(color, "\t".repeat(indent) + "---".repeat(3) + " Stop details " + "---".repeat(3)); + Logger.getInstance().print(color, "\t".repeat(indent) + name); + + for (Passenger p : passengers) { + p.printDetails(indent + 1); + } + } public void printDetails(int indent) { Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Stop details " + "---".repeat(3)); @@ -77,8 +93,24 @@ public class Stop implements Runnable { printDetails(0); } + public void busArrive() { + synchronized(this) { + mutex.lock(); + } + } + + public void busLeave() { + synchronized(this) { + mutex.unlock(); + } + } + public void removePassenger(Passenger p) { // Logger.getInstance().print(id, "Passenger " + p.getName() + " left " + name); - passengers.remove(p); + try { + passengers.remove(p); + } catch(Exception e) { + System.out.println("exception" + e.getMessage()); + } } }