Created
          June 28, 2013 18:19 
        
      - 
      
- 
        Save xyos/5886830 to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package pf; | |
| import java.util.ArrayList; | |
| import java.util.concurrent.locks.Condition; | |
| import java.util.concurrent.locks.Lock; | |
| import java.util.concurrent.locks.ReentrantLock; | |
| public class Boat { | |
| private static final PersonType Adult = PersonType.Adult; | |
| private static final PersonType Child = PersonType.Child; | |
| private static final Location Oahu = Location.Oahu; | |
| private static final Location Molokai = Location.Molokai; | |
| private static final ArrayList<Person> boat = new ArrayList<Person>(); | |
| private static BoatGrader grader; | |
| private static Location boatLocation; | |
| private static int adultsO; | |
| private static int childrenO; | |
| private static int adultsM; | |
| private static int childrenM; | |
| private static Lock boatLock; | |
| private static Lock finishLock; | |
| private static Condition isEmptyAndNoChildOnO; | |
| private static Condition isEmptyAndOneChildOnO; | |
| private static Condition hasPilot; | |
| private static Condition isOnLand; | |
| private static Condition isEmptyM; | |
| private static Condition isFinished; | |
| private static boolean debug; | |
| private static boolean childOnO; | |
| private static boolean finished; | |
| public static void main(String[] args) throws InterruptedException { | |
| System.out.println("\nprobando:\n2 niños oahu;\n2 adultos , 1 niño molokai\n\n "); | |
| begin(100, 220, 20, 13, true); | |
| /* System.out.println("\nprobando: 1 niño , 2 adultos oahu;\n1 adulto, 2 niños molokai n "); | |
| begin(1, 2, 2, 1, false); | |
| System.out.println("\nprobando: 5 niños , 3 adultos oahu;\n1 adulto, 2 niños molokai n "); | |
| begin(5, 3, 1, 2, false);*/ | |
| System.out.println("\nTerminando"); | |
| System.out.println("Adultos, Niños Oahu:" + adultsO + "," + childrenO + " Molokai:" + adultsM + "," + childrenM); | |
| System.exit(0); | |
| } | |
| private static void begin(int adults_o, int children_o, int adults_m, int children_m, boolean dbg) throws InterruptedException { | |
| debug = dbg; | |
| assert (adults_o >= 0 && children_o >= 2); | |
| grader = new BoatGrader(); | |
| adultsO = childrenO = adultsM = childrenM = 0; | |
| adultsM = adults_m; | |
| childrenM = children_m; | |
| if (debug) { | |
| if (adultsM > 0) { | |
| System.out.println("Creando Adultos en Molokai"); | |
| debug(); | |
| } | |
| if (childrenM > 0) { | |
| System.out.println("Creando niños en Molokai"); | |
| debug(); | |
| } | |
| } | |
| childOnO = finished = false; | |
| boatLocation = Oahu; | |
| boatLock = new ReentrantLock(); | |
| isEmptyAndNoChildOnO = boatLock.newCondition(); | |
| isEmptyAndOneChildOnO = boatLock.newCondition(); | |
| isEmptyM = boatLock.newCondition(); | |
| hasPilot = boatLock.newCondition(); | |
| isOnLand = boatLock.newCondition(); | |
| finishLock = new ReentrantLock(); | |
| isFinished = finishLock.newCondition(); | |
| finishLock.lock(); | |
| for (int i = 0; i < adults_o; i++) { | |
| Thread adultThread = new Thread(new Person(Adult)); | |
| adultThread.setName("Adulto_" + i); | |
| adultThread.start(); | |
| } | |
| for (int i = 0; i < children_o; i++) { | |
| Thread childThread = new Thread(new Person(Child)); | |
| childThread.setName("Niño_" + i); | |
| childThread.start(); | |
| } | |
| while (!finished) { | |
| isFinished.await(); | |
| if (childrenM + adultsM == adults_o + children_o + adults_m + children_m) | |
| finished = true; | |
| else { | |
| System.out.println("aun no hemos terminado"); | |
| isEmptyM.signal(); | |
| } | |
| } | |
| finishLock.unlock(); | |
| System.out.println("terminado"); | |
| } | |
| private static void debug() { | |
| if (debug) { | |
| System.out.println("Adultos, Niños Oahu:" + adultsO + "," + childrenO + " Molokai:" + adultsM + "," + childrenM); | |
| } | |
| } | |
| private static void AdultItinerary(Person adult) throws InterruptedException { | |
| /* | |
| * This is where you should put your solutions. Make calls to the | |
| * BoatGrader to show that it is synchronized. For example: | |
| * bg.AdultRowToMolokai(); indicates that an adult has rowed the boat | |
| * across to Molokai | |
| */ | |
| assert (adult.location == Oahu); | |
| adultsO++; | |
| if (debug) { | |
| System.out.print("creando " + Thread.currentThread().getName() + " en Oahu\n "); | |
| debug(); | |
| } | |
| loadAdult(adult); | |
| grader.AdultRowToMolokai(); | |
| adultGoToM(adult); | |
| } | |
| private static void ChildItinerary(Person child) throws InterruptedException { | |
| childrenO++; // could just do this in Person constructor but maybe cheating? | |
| if (debug) { | |
| System.out.print("creando " + Thread.currentThread().getName() + " en Oahu\n "); | |
| debug(); | |
| } | |
| while (!finished) { | |
| if (child.location == Oahu) { | |
| if (loadTwoChildren(child)) { | |
| grader.ChildRowToMolokai(); | |
| childGoToM(child); | |
| } else { | |
| grader.ChildRideToMolokai(); | |
| ChildTravelToM(child); | |
| } | |
| } else if (child.peopleLastIsland != 0) { // go back to Oahu | |
| loadChild(child); | |
| grader.ChildRowToOahu(); | |
| childGoToO(child); | |
| } | |
| Thread.yield(); | |
| } | |
| } | |
| private static void loadAdult(Person adult) throws InterruptedException { | |
| boatLock.lock(); | |
| while (childrenO != 1 || boatLocation != Oahu || !boat.isEmpty() || !childOnO) { | |
| isEmptyAndOneChildOnO.await(); | |
| } | |
| if (debug) { | |
| System.out.println(Thread.currentThread() + " se subió al bote"); | |
| } | |
| boat.add(adult); | |
| boatLock.unlock(); | |
| } | |
| private static void loadChild(Person child) throws InterruptedException { | |
| boatLock.lock(); | |
| while (boatLocation != Molokai || !boat.isEmpty() || finished) { | |
| isEmptyM.await(); | |
| } | |
| System.out.println("el " + Thread.currentThread().getName() + " es piloto"); | |
| boat.add(child); | |
| boatLock.unlock(); | |
| } | |
| private static boolean loadTwoChildren(Person child) throws InterruptedException { | |
| boatLock.lock(); | |
| if (!childOnO) | |
| childOnO = true; | |
| else | |
| while (childrenO == 1 || boatLocation != Oahu || boat.size() >= 2) { | |
| isEmptyAndNoChildOnO.await(); | |
| } | |
| boat.add(child); | |
| if (boat.size() == 2) { | |
| if (debug) { | |
| System.out.println("el " + Thread.currentThread().getName() + " es pasajero"); | |
| } | |
| hasPilot.signal(); | |
| while (boat.size() == 2) | |
| isOnLand.await(); | |
| boatLock.unlock(); | |
| return false; | |
| } else { //child is rower | |
| if (debug) { | |
| System.out.println("el " + Thread.currentThread().getName() + " es piloto"); | |
| } | |
| while (boat.size() != 2) | |
| hasPilot.await(); | |
| boatLock.unlock(); | |
| return true; | |
| } | |
| } | |
| private static void unload(Person person) { | |
| boatLock.lock(); | |
| if (debug) { | |
| System.out.println("el " + Thread.currentThread().getName() + " se bajo del bote"); | |
| debug(); | |
| } | |
| boat.remove(person); | |
| if (boat.isEmpty()) { | |
| if (boatLocation == Molokai) { | |
| if (person.peopleLastIsland == 0) { | |
| finishLock.lock(); | |
| isFinished.signal(); | |
| finishLock.unlock(); | |
| } else | |
| isEmptyM.signal(); | |
| } else if (childrenO == 1) | |
| isEmptyAndOneChildOnO.signal(); | |
| else | |
| isEmptyAndNoChildOnO.signal(); | |
| } | |
| boatLock.unlock(); | |
| } | |
| private static void adultGoToM(Person adult) { | |
| adult.peopleLastIsland = childrenO + adultsO - 1; | |
| adultsO--; | |
| adultsM++; | |
| boatLocation = Molokai; | |
| unload(adult); | |
| adult.location = Molokai; | |
| } | |
| private static void childGoToM(Person child) { | |
| child.peopleLastIsland = childrenO + adultsO - 2; | |
| childrenO--; | |
| childrenM++; | |
| boatLocation = Molokai; | |
| unload(child); | |
| child.location = Molokai; | |
| boatLock.lock(); | |
| isOnLand.signal(); | |
| boatLock.unlock(); | |
| } | |
| private static void ChildTravelToM(Person child) { | |
| child.peopleLastIsland = childrenO + adultsO - 1; | |
| childrenO--; | |
| childrenM++; | |
| boatLocation = Molokai; | |
| unload(child); | |
| child.location = Molokai; | |
| } | |
| private static void childGoToO(Person child) { | |
| child.peopleLastIsland = childrenM + adultsM - 1; | |
| childrenM--; | |
| childrenO++; | |
| boatLocation = Oahu; | |
| unload(child); | |
| child.location = Oahu; | |
| } | |
| enum PersonType {Adult, Child} | |
| enum Location {Oahu, Molokai} | |
| static class Person implements Runnable { | |
| final PersonType type; | |
| Location location; | |
| int peopleLastIsland; | |
| Person(PersonType t) { | |
| location = Oahu; | |
| type = t; | |
| } | |
| public void run() { | |
| if (type == Adult) | |
| try { | |
| AdultItinerary(this); | |
| } catch (InterruptedException e) { | |
| e.printStackTrace(); | |
| } | |
| else | |
| try { | |
| ChildItinerary(this); | |
| } catch (InterruptedException e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | package pf; | |
| public class BoatGrader { | |
| /** | |
| * BoatGrader consists of functions to be called to show that your solution | |
| * is properly synchronized. This version simply prints messages to standard | |
| * out, so that you can watch it. You cannot submit this file, as we will be | |
| * using our own version of it during grading. | |
| * | |
| * Note that this file includes all possible variants of how someone can get | |
| * from one island to another. Inclusion in this class does not imply that | |
| * any of the indicated actions are a good idea or even allowed. | |
| */ | |
| /* | |
| * ChildRowToMolokai should be called when a child pilots the boat from Oahu | |
| * to Molokai | |
| */ | |
| public void ChildRowToMolokai() { | |
| System.out.println("**Child rowing to Molokai."); | |
| } | |
| /* | |
| * ChildRowToOahu should be called when a child pilots the boat from Molokai | |
| * to Oahu | |
| */ | |
| public void ChildRowToOahu() { | |
| System.out.println("**Child rowing to Oahu."); | |
| } | |
| /* | |
| * ChildRideToMolokai should be called when a child not piloting the boat | |
| * disembarks on Molokai | |
| */ | |
| public void ChildRideToMolokai() { | |
| System.out.println("**Child arrived on Molokai as a passenger."); | |
| } | |
| /* | |
| * ChildRideToOahu should be called when a child not piloting the boat | |
| * disembarks on Oahu | |
| */ | |
| public void ChildRideToOahu() { | |
| System.out.println("**Child arrived on Oahu as a passenger."); | |
| } | |
| /* | |
| * AdultRowToMolokai should be called when a adult pilots the boat from Oahu | |
| * to Molokai | |
| */ | |
| public void AdultRowToMolokai() { | |
| System.out.println("**Adult rowing to Molokai."); | |
| } | |
| /* | |
| * AdultRowToOahu should be called when a adult pilots the boat from Molokai | |
| * to Oahu | |
| */ | |
| public void AdultRowToOahu() { | |
| System.out.println("**Adult rowing to Oahu."); | |
| } | |
| /* | |
| * AdultRideToMolokai should be called when an adult not piloting the boat | |
| * disembarks on Molokai | |
| */ | |
| public void AdultRideToMolokai() { | |
| System.out.println("**Adult arrived on Molokai as a passenger."); | |
| } | |
| /* | |
| * AdultRideToOahu should be called when an adult not piloting the boat | |
| * disembarks on Oahu | |
| */ | |
| public void AdultRideToOahu() { | |
| System.out.println("**Adult arrived on Oahu as a passenger."); | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment