Q3 done!
This commit is contained in:
parent
3b99a35740
commit
16fe398f5f
4 changed files with 135 additions and 79 deletions
|
@ -13,22 +13,24 @@ public class App {
|
||||||
static private int numStopPerBus = 8;
|
static private int numStopPerBus = 8;
|
||||||
static private int numStops = numBusses * numStopPerBus;
|
static private int numStops = numBusses * numStopPerBus;
|
||||||
static private int numPassengersPerBus = 10;
|
static private int numPassengersPerBus = 10;
|
||||||
static private int numPassengersPerStop = 3;
|
static private int numPassengersPerStop = 3;
|
||||||
static private int numPassengers = numPassengersPerStop * numStops;
|
static private int numPassengers = numPassengersPerStop * numStops;
|
||||||
static private int numThreadsBus = 5;
|
static private int numThreadsBus = 5;
|
||||||
static private int numThreadsStop = 2;
|
static private int numThreadsStop = 2;
|
||||||
static private int timeBetweenStops = 5;
|
static private int timeBetweenStops = 5;
|
||||||
static private int timeEmbark = 2;
|
static private int timeEmbark = 2;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ExecutorService threadsBus = Executors.newFixedThreadPool(numThreadsBus);
|
ExecutorService threadsBus = Executors.newFixedThreadPool(numThreadsBus);
|
||||||
ExecutorService threadsStop = Executors.newFixedThreadPool(numThreadsStop);
|
ExecutorService threadsStop = Executors.newFixedThreadPool(numThreadsStop);
|
||||||
ArrayList<Stop> stops = new ArrayList<Stop>();
|
ExecutorService threadsPassenger = Executors.newFixedThreadPool(1); // doesnt need more! future balance
|
||||||
ArrayList<Bus> busses = new ArrayList<Bus>();
|
// themselfes out.
|
||||||
ArrayList<Passenger> passengers = new ArrayList<Passenger>();
|
ArrayList<Stop> stops = new ArrayList<Stop>();
|
||||||
BlockingQueue<BusInformationMessage> blockingQueue = new LinkedBlockingQueue<BusInformationMessage>();
|
ArrayList<Bus> busses = new ArrayList<Bus>();
|
||||||
|
ArrayList<Passenger> passengers = new ArrayList<Passenger>();
|
||||||
|
BlockingQueue<BusInformationMessage> blockingQueue = new LinkedBlockingQueue<BusInformationMessage>();
|
||||||
|
|
||||||
// make stops
|
// make stop" + name + " reached stop " + nextStop.getStopName() + "!"s
|
||||||
for (int k = 0; k < numStops; k++) {
|
for (int k = 0; k < numStops; k++) {
|
||||||
Stop s = new Stop(k, numPassengersPerStop);
|
Stop s = new Stop(k, numPassengersPerStop);
|
||||||
s.setBlockingQueue(blockingQueue);
|
s.setBlockingQueue(blockingQueue);
|
||||||
|
@ -36,14 +38,14 @@ public class App {
|
||||||
stops.add(s);
|
stops.add(s);
|
||||||
s.setThreadPool(threadsStop);
|
s.setThreadPool(threadsStop);
|
||||||
threadsStop.submit(s);
|
threadsStop.submit(s);
|
||||||
//s.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// make busses
|
// make busses
|
||||||
for (int k = 0; k < numBusses; k++) {
|
for (int k = 0; k < numBusses; k++) {
|
||||||
if (numStopPerBus > numStops)
|
if (numStopPerBus > numStops) {
|
||||||
{System.out.println("More stops per bus than stops."); return;}
|
System.out.println("More stops per bus than stops.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ArrayList<Stop> s_list = new ArrayList<Stop>();
|
ArrayList<Stop> s_list = new ArrayList<Stop>();
|
||||||
Stop s;
|
Stop s;
|
||||||
|
@ -67,7 +69,7 @@ public class App {
|
||||||
for (Stop start : b.getStops()) {
|
for (Stop start : b.getStops()) {
|
||||||
|
|
||||||
// make sure passenger can leave.
|
// make sure passenger can leave.
|
||||||
if (start == b.getTerminus())
|
if (start == b.getTerminus())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int idx = b.getStops().indexOf(start);
|
int idx = b.getStops().indexOf(start);
|
||||||
|
@ -80,9 +82,12 @@ public class App {
|
||||||
dest = b.getStops().get(idx + 1 + (int) Math.round(Math.random() * (numStopPerBus - 2 - idx)));
|
dest = b.getStops().get(idx + 1 + (int) Math.round(Math.random() * (numStopPerBus - 2 - idx)));
|
||||||
|
|
||||||
Passenger p = new Passenger(idPassenger, start, dest);
|
Passenger p = new Passenger(idPassenger, start, dest);
|
||||||
|
p.setThreadPool(threadsPassenger);
|
||||||
passengers.add(p);
|
passengers.add(p);
|
||||||
start.addPassenger(p);
|
start.addPassenger(p);
|
||||||
idPassenger++;
|
idPassenger++;
|
||||||
|
|
||||||
|
threadsPassenger.submit(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,11 +111,15 @@ public class App {
|
||||||
threadsBus.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
threadsBus.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
||||||
} catch (InterruptedException e) {}
|
} catch (InterruptedException e) {}
|
||||||
|
|
||||||
// block stop pool once bus have finished
|
// block stop and passenger pool once bus have finished
|
||||||
|
|
||||||
threadsStop.shutdown();
|
threadsStop.shutdown();
|
||||||
|
threadsPassenger.shutdown();
|
||||||
try {
|
try {
|
||||||
threadsStop.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
threadsStop.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
||||||
} catch (InterruptedException e) {}
|
} catch (InterruptedException e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
threadsPassenger.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
||||||
|
} catch (InterruptedException e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,20 @@ package usherbrooke.ift630;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public class Bus extends Thread {
|
public class Bus extends Thread {
|
||||||
private ArrayList<Passenger> passengers;
|
private ArrayList<Passenger> passengers;
|
||||||
private ArrayList<Stop> stops;
|
private ArrayList<Stop> stops;
|
||||||
private String name;
|
private String name;
|
||||||
private int id;
|
private int id;
|
||||||
private int maxCapacity;
|
private int maxCapacity;
|
||||||
private int currentCapacity;
|
private int currentCapacity;
|
||||||
private int timeBetweenStops;
|
private int timeBetweenStops;
|
||||||
private int timeToNextStop;
|
private int timeToNextStop;
|
||||||
private int timeEmbark;
|
private int timeEmbark;
|
||||||
private Stop nextStop;
|
private Stop nextStop;
|
||||||
private BlockingQueue<BusInformationMessage> blockingQueue;
|
private BlockingQueue<BusInformationMessage> blockingQueue;
|
||||||
|
|
||||||
// returns time for a single passenger to embark.
|
// returns time for a single passenger to embark.
|
||||||
private int timeEmbark() {
|
private int timeEmbark() {
|
||||||
|
@ -23,14 +24,14 @@ public class Bus extends Thread {
|
||||||
|
|
||||||
// set time between stop.
|
// set time between stop.
|
||||||
private int calculateTimeBetweenStops() {
|
private int calculateTimeBetweenStops() {
|
||||||
timeToNextStop = (int) ((timeBetweenStops / 3) + (Math.random() * 2 * timeBetweenStops / 3));
|
timeToNextStop = (int) ((timeBetweenStops / 3) + (Math.random() * 2 * timeBetweenStops / 3));
|
||||||
return timeToNextStop;
|
return timeToNextStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if a passenger must leave at next stop.
|
// check if a passenger must leave at next stop.
|
||||||
private boolean stopAsked() {
|
private boolean stopAsked() {
|
||||||
boolean res = false;
|
boolean res = false;
|
||||||
for (Passenger p : passengers){
|
for (Passenger p : passengers) {
|
||||||
if (p.getDest() == nextStop) {
|
if (p.getDest() == nextStop) {
|
||||||
res = true;
|
res = true;
|
||||||
Logger.getInstance().print(id, "[BUS] " + name + " stop asked!");
|
Logger.getInstance().print(id, "[BUS] " + name + " stop asked!");
|
||||||
|
@ -65,9 +66,9 @@ public class Bus extends Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
// send Bus info msg to next stop
|
// send Bus info msg to next stop
|
||||||
private void sendNextStopInfo() throws InterruptedException{
|
private void sendNextStopInfo() throws InterruptedException {
|
||||||
BusInformationMessage info = new BusInformationMessage(this, nextStop, timeToNextStop);
|
BusInformationMessage info = new BusInformationMessage(this, nextStop, timeToNextStop);
|
||||||
synchronized(blockingQueue) {
|
synchronized (blockingQueue) {
|
||||||
blockingQueue.put(info);
|
blockingQueue.put(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,22 +121,22 @@ public class Bus extends Thread {
|
||||||
nextStop = null;
|
nextStop = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
Logger.getInstance().print(id, "[BUS] exception: " + e.toString());
|
Logger.getInstance().print(id, "[BUS] exception: " + e.toString());
|
||||||
}
|
}
|
||||||
Logger.getInstance().print(id, "[BUS] " + name + " exiting!");
|
Logger.getInstance().print(id, "[BUS] " + name + " exiting!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Bus(ArrayList<Stop> s, int id, int timeStop, int timeEmbark, int maxCapacity) {
|
Bus(ArrayList<Stop> s, int id, int timeStop, int timeEmbark, int maxCapacity) {
|
||||||
this.timeBetweenStops = timeStop * 1000 + 1;
|
this.timeBetweenStops = timeStop * 1000 + 1;
|
||||||
this.timeEmbark = timeEmbark * 1000 + 1;
|
this.timeEmbark = timeEmbark * 1000 + 1;
|
||||||
this.name = "Bus n°" + id;
|
this.name = "Bus n°" + id;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.passengers = new ArrayList<Passenger>();
|
this.passengers = new ArrayList<Passenger>();
|
||||||
this.stops = s;
|
this.stops = s;
|
||||||
this.nextStop = stops.get(0);
|
this.nextStop = stops.get(0);
|
||||||
this.currentCapacity = 0;
|
this.currentCapacity = 0;
|
||||||
this.maxCapacity = maxCapacity;
|
this.maxCapacity = maxCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
// disembark passenger at a stop. Synchronizes, locks on that stop, and waits.
|
// disembark passenger at a stop. Synchronizes, locks on that stop, and waits.
|
||||||
|
@ -145,11 +146,11 @@ public class Bus extends Thread {
|
||||||
for (Passenger p : passengers) {
|
for (Passenger p : passengers) {
|
||||||
waitEmbark();
|
waitEmbark();
|
||||||
|
|
||||||
Logger.getInstance().print(id,
|
|
||||||
"\t[DISEMBARK] " + p.getName() + " at " + nextStop.getStopName());
|
|
||||||
|
|
||||||
if (p.getDest() == nextStop) {
|
if (p.getDest() == nextStop) {
|
||||||
p.disembark();
|
synchronized (p) {
|
||||||
|
p.notify();
|
||||||
|
}
|
||||||
|
// already synced on this, func is synced
|
||||||
currentCapacity--;
|
currentCapacity--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,15 +164,15 @@ public class Bus extends Thread {
|
||||||
try {
|
try {
|
||||||
ArrayList<Passenger> list = nextStop.getPassengerByDest(stops);
|
ArrayList<Passenger> list = nextStop.getPassengerByDest(stops);
|
||||||
for (Passenger p : list) {
|
for (Passenger p : list) {
|
||||||
|
synchronized (p) {
|
||||||
|
p.notify();
|
||||||
|
}
|
||||||
waitEmbark();
|
waitEmbark();
|
||||||
if (currentCapacity >= maxCapacity)
|
if (currentCapacity >= maxCapacity)
|
||||||
continue;
|
continue;
|
||||||
passengers.add(p);
|
passengers.add(p);
|
||||||
nextStop.removePassenger(p);
|
nextStop.removePassenger(p);
|
||||||
currentCapacity++;
|
currentCapacity++;
|
||||||
|
|
||||||
Logger.getInstance().print(id,
|
|
||||||
"\t[EMBARK] " + p.getName() + " at " + nextStop.getStopName());
|
|
||||||
}
|
}
|
||||||
} catch (IndexOutOfBoundsException e) {
|
} catch (IndexOutOfBoundsException e) {
|
||||||
Logger.getInstance().print(id, "Exception: " + e.getMessage());
|
Logger.getInstance().print(id, "Exception: " + e.getMessage());
|
||||||
|
@ -188,7 +189,6 @@ public class Bus extends Thread {
|
||||||
Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + nextStop.getStopName());
|
Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + nextStop.getStopName());
|
||||||
Logger.getInstance().print(id, "\t".repeat(indent) + "stops: ");
|
Logger.getInstance().print(id, "\t".repeat(indent) + "stops: ");
|
||||||
|
|
||||||
|
|
||||||
if (nextStop != stops.get(0))
|
if (nextStop != stops.get(0))
|
||||||
nextStop.printDetails(id, indent + 1);
|
nextStop.printDetails(id, indent + 1);
|
||||||
for (Stop s : stops) {
|
for (Stop s : stops) {
|
||||||
|
|
|
@ -1,24 +1,57 @@
|
||||||
package usherbrooke.ift630;
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
public class Passenger {
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
private String name;
|
public class Passenger extends Thread {
|
||||||
private int id;
|
|
||||||
private Stop dest;
|
|
||||||
private Stop start;
|
|
||||||
|
|
||||||
Passenger(int id, Stop start, Stop dest) {
|
private String name;
|
||||||
|
private int id;
|
||||||
|
private Stop dest;
|
||||||
|
private Stop start;
|
||||||
|
private ExecutorService threads;
|
||||||
|
private ExecutorService ex;
|
||||||
|
private Future<Void> future;
|
||||||
|
|
||||||
|
Passenger(int id, Stop start, Stop dest) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = "Passenger " + id;
|
this.name = "Passenger " + id;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.start = start;
|
this.start = start;
|
||||||
}
|
this.ex = Executors.newFixedThreadPool(2); // one for each future.
|
||||||
|
}
|
||||||
|
|
||||||
// unused, *yet*
|
public void run() {
|
||||||
public synchronized void embark() {}
|
try {
|
||||||
|
embark();
|
||||||
|
disembark();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.getInstance().print(id, "[PASSENGER] " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// unused, *yet*
|
// embark people once thread notified
|
||||||
public synchronized void disembark() {}
|
private synchronized Future<Void> embark() {
|
||||||
|
return ex.submit(() -> {
|
||||||
|
synchronized (this) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
Logger.getInstance().print(id, "\t[PASSENGER] I'm embarking at " + start.getStopName());
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// disembark people once thread notified another time.
|
||||||
|
private synchronized Future<Void> disembark() {
|
||||||
|
return ex.submit(() -> {
|
||||||
|
synchronized (this) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
Logger.getInstance().print(id, "\t[PASSENGER] I'm leaving at " + dest.getStopName());
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public Stop getStart() {
|
public Stop getStart() {
|
||||||
return start;
|
return start;
|
||||||
|
@ -28,24 +61,31 @@ public class Passenger {
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getPassengerName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretty print, with color!
|
// Pretty print, with color!
|
||||||
public void printDetails(int color, int indent) {
|
public void printDetails(int color, int indent) {
|
||||||
Logger.getInstance().print(color, "\t".repeat(indent) + "---".repeat(3) + " Passenger details " + "---".repeat(3));
|
Logger.getInstance().print(color,
|
||||||
Logger.getInstance().print(color, "\t".repeat(indent) + name + " start: " + start.getStopName() + " dest: " + dest.getStopName());
|
"\t".repeat(indent) + "---".repeat(3) + " Passenger details " + "---".repeat(3));
|
||||||
|
Logger.getInstance().print(color,
|
||||||
|
"\t".repeat(indent) + name + " start: " + start.getStopName() + " dest: " + dest.getStopName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretty print, with indent!
|
// Pretty print, with indent!
|
||||||
public void printDetails(int indent) {
|
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) + "---".repeat(3) + " Passenger details " + "---".repeat(3));
|
||||||
Logger.getInstance().print(id, "\t".repeat(indent) + name + " start: " + start.getStopName() + " dest: " + dest.getStopName());
|
Logger.getInstance().print(id,
|
||||||
|
"\t".repeat(indent) + name + " start: " + start.getStopName() + " dest: " + dest.getStopName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pretty print!
|
// Pretty print!
|
||||||
public void printDetails() {
|
public void printDetails() {
|
||||||
printDetails(0);
|
printDetails(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setThreadPool(ExecutorService threads) {
|
||||||
|
this.threads = threads;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
package usherbrooke.ift630;
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Stop extends Thread {
|
public class Stop extends Thread {
|
||||||
private String name;
|
private String name;
|
||||||
private int id;
|
private int id;
|
||||||
private int maxCapacity;
|
private int maxCapacity;
|
||||||
private int indent = 0;
|
private int indent = 0;
|
||||||
private ArrayList<Passenger> passengers;
|
private ArrayList<Passenger> passengers;
|
||||||
private ExecutorService threads;
|
private ExecutorService threads;
|
||||||
private BlockingQueue<BusInformationMessage> blockingQueue;
|
private BlockingQueue<BusInformationMessage> blockingQueue;
|
||||||
|
|
||||||
|
|
||||||
// print bus info times.
|
// print bus info times.
|
||||||
private void displayInfos(int indent) throws InterruptedException, ExitException{
|
private void displayInfos(int indent) throws InterruptedException, ExitException {
|
||||||
BusInformationMessage info = null;
|
BusInformationMessage info = null;
|
||||||
|
|
||||||
// lock queue, get head
|
// lock queue, get head
|
||||||
|
@ -30,7 +30,8 @@ public class Stop extends Thread {
|
||||||
Logger.getInstance().print(id,
|
Logger.getInstance().print(id,
|
||||||
"\t".repeat(indent) + "[STOP] " + info.getBus(this).getNameBus() + " arrives in " + time + "s");
|
"\t".repeat(indent) + "[STOP] " + info.getBus(this).getNameBus() + " arrives in " + time + "s");
|
||||||
// else, catch
|
// else, catch
|
||||||
} catch (NullPointerException e) {}
|
} catch (NullPointerException e) {
|
||||||
|
}
|
||||||
|
|
||||||
} catch (UnauthorizedException e) {
|
} catch (UnauthorizedException e) {
|
||||||
// if unauth, requeue message.
|
// if unauth, requeue message.
|
||||||
|
@ -41,8 +42,13 @@ public class Stop extends Thread {
|
||||||
|
|
||||||
// loop, and ensure that every stop is reactive
|
// loop, and ensure that every stop is reactive
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
threads.submit(this);
|
// i dont have access to virtual threads, and futures are for the next question.
|
||||||
|
// to not hog allof the pool's capacity,
|
||||||
|
// i have to manualy change threads in action. This is done by submiting this
|
||||||
|
// thread, waiting a bit (dont blow up our CPU) then exit. This ensure that
|
||||||
|
// another thread takes the slot, if it there is one.
|
||||||
sleep(10);
|
sleep(10);
|
||||||
|
threads.submit(this);
|
||||||
throw new ExitException();
|
throw new ExitException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +59,8 @@ public class Stop extends Thread {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
displayInfos(indent);
|
displayInfos(indent);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException | ExitException e) {}
|
} catch (InterruptedException | ExitException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stop(int id, int maxCapacity) {
|
Stop(int id, int maxCapacity) {
|
||||||
|
@ -118,7 +125,7 @@ public class Stop extends Thread {
|
||||||
printDetails(0);
|
printDetails(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removePassenger(Passenger p) {
|
public synchronized void removePassenger(Passenger p) {
|
||||||
try {
|
try {
|
||||||
passengers.remove(p);
|
passengers.remove(p);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
Loading…
Reference in a new issue