Crazy

Tribe Dinner 2.0

Mar 29th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 19.30 KB | None | 0 0
  1. import java.util.*;
  2. import java.util.concurrent.Semaphore;
  3.  
  4.  
  5. public class SeptemberTribeDinner {
  6.  
  7.  
  8.  
  9.     static Semaphore checkPot;
  10.  
  11.     static Semaphore canEat;
  12.  
  13.     static Semaphore cook;
  14.  
  15.     static Semaphore foodCooked;
  16.  
  17.  
  18.  
  19.     public static void init() {
  20.  
  21.         checkPot= new Semaphore(1);
  22.  
  23.         canEat= new Semaphore(4);
  24.  
  25.         cook = new Semaphore(0);
  26.  
  27.         foodCooked = new Semaphore(0);
  28.  
  29.  
  30.  
  31.  
  32.  
  33.     }
  34.  
  35.     public static class TribeMember extends TemplateThread {
  36.  
  37.         public TribeMember(int numRuns) {
  38.             super(numRuns);
  39.         }
  40.  
  41.         @Override
  42.         public void execute() throws InterruptedException {
  43.  
  44.             // Vashiot kod ovde
  45.  
  46.  
  47.             checkPot.acquire();
  48.  
  49.             if (state.isPotEmpty()){
  50.                 cook.release();
  51.                 foodCooked.acquire();
  52.  
  53.             }
  54.  
  55.             state.fillPlate();
  56.             checkPot.release();
  57.  
  58.  
  59.             canEat.acquire();
  60.             state.eat();
  61.             canEat.release();
  62.  
  63.  
  64.  
  65.  
  66.  
  67.         }
  68.  
  69.     }
  70.  
  71.     public static class Chef extends TemplateThread {
  72.  
  73.         public Chef(int numRuns) {
  74.             super(numRuns);
  75.         }
  76.  
  77.         @Override
  78.         public void execute() throws InterruptedException {
  79.             // Vashiot kod ovde
  80.  
  81.  
  82.             cook.acquire();
  83.             state.cook();
  84.             foodCooked.release();
  85.  
  86.  
  87.         }
  88.  
  89.     }
  90.  
  91.     static SeptemberTribeDinnerState state = new SeptemberTribeDinnerState();
  92.  
  93.     public static void main(String[] args) {
  94.         for (int i = 0; i < 3; i++) {
  95.             run();
  96.         }
  97.     }
  98.  
  99.     public static void run() {
  100.         try {
  101.             int numRuns = 1;
  102.             int numIterations = 150;
  103.  
  104.             HashSet<Thread> threads = new HashSet<Thread>();
  105.  
  106.             for (int i = 0; i < numIterations; i++) {
  107.                 TribeMember h = new TribeMember(numRuns);
  108.                 threads.add(h);
  109.             }
  110.  
  111.             Chef chef = new Chef(10);
  112.             threads.add(chef);
  113.  
  114.             init();
  115.  
  116.             ProblemExecution.start(threads, state);
  117.             //System.out.println(new Date().getTime());
  118.         } catch (Exception ex) {
  119.             ex.printStackTrace();
  120.         }
  121.     }
  122. }
  123.  
  124.  
  125.  
  126. class SeptemberTribeDinnerState extends AbstractState {
  127.  
  128.     private static final int EMPTY_POT = 0;
  129.  
  130.     private static final String _10_JADENJETO_NE_E_PARALELIZIRANO = "jadenjeto ne e paralelizirano. Site jadat eden po eden";
  131.  
  132.     private static final String _10_DVAJCA_ISTOVREMENO_PROVERUVAAT = "Dvajca istovremeno proveruvaat dali kazanot e prazen. Maksimum eden e dozvoleno.";
  133.     private static final String _7_DVAJCA_ISTOVREMENO_POLNAT = "Dvajca istovremeno zemaat hrana od kazanot. Maksimum eden e dozvoleno.";
  134.     private static final String _5_NE_MOZE_DA_POLNI_OD_PRAZEN_KAZAN = "Ne moze da se polni od kazan. Treba da se povika 'state.cook()'";
  135.     private static final String _5_NE_MOZE_DA_SE_GOTVI_VO_KAZAN_KOJ_NE_E_PRAZEN = "Ne moze da se gotvi vo kazan koj ne e prazen";
  136.     private static final String _7_NEMA_MESTO_NA_TRPEZATA = "Trpezata e polna. Nema mesto na trpezata za poveke od cetvorica. ";
  137.     private static final String _7_NEMA_ZEMENO_HRANA = "NEMA ZEMENO HRANA";
  138.     private static final String _7_POLNI_OD_PRAZEN_KAZAN = "POLNI OD PRAZEN KAZAN";
  139.  
  140.     private static final int POT_CAPACITY = 15;
  141.  
  142.     private BoundCounterWithRaceConditionCheck platesLeft = new BoundCounterWithRaceConditionCheck(
  143.             0, null, 0, null, 0, 10, _7_POLNI_OD_PRAZEN_KAZAN);
  144.  
  145.     private BoundCounterWithRaceConditionCheck checks = new BoundCounterWithRaceConditionCheck(
  146.             0, 1, 10, _10_DVAJCA_ISTOVREMENO_PROVERUVAAT, null, 0, null);
  147.  
  148.     private BoundCounterWithRaceConditionCheck fills = new BoundCounterWithRaceConditionCheck(
  149.             0, 1, 7, _7_DVAJCA_ISTOVREMENO_POLNAT, 0, 5,
  150.             _5_NE_MOZE_DA_POLNI_OD_PRAZEN_KAZAN);
  151.  
  152.     private BoundCounterWithRaceConditionCheck ready = new BoundCounterWithRaceConditionCheck(
  153.             0, null, 0, null, 0, 7, _7_NEMA_ZEMENO_HRANA);
  154.  
  155.     private BoundCounterWithRaceConditionCheck eat = new BoundCounterWithRaceConditionCheck(
  156.             0, 4, 7, _7_NEMA_MESTO_NA_TRPEZATA, null, 0, null);
  157.  
  158.     public SeptemberTribeDinnerState() {
  159.  
  160.     }
  161.  
  162.     /**
  163.      * Maksimum 1 proveruva.
  164.      *
  165.      * @return
  166.      * @throws RuntimeException
  167.      */
  168.     public boolean isPotEmpty() throws RuntimeException {
  169.         log(checks.incrementWithMax(), "proverka dali ima hrana vo kazanot");
  170.         boolean res = platesLeft.getValue() == 0;
  171.         log(checks.decrementWithMin(), null);
  172.         return res;
  173.     }
  174.  
  175.     /**
  176.      * Maksimum 1 zema paralelno. Ne smee da se povika od prazen kazan.
  177.      *
  178.      * @throws RuntimeException
  179.      */
  180.     public void fillPlate() throws RuntimeException {
  181.         log(fills.incrementWithMax(), "zemanje na hrana");
  182.         log(platesLeft.decrementWithMin(false), null);
  183.         log(fills.decrementWithMin(), null);
  184.         ready.incrementWithMax(false);
  185.     }
  186.  
  187.     /**
  188.      * Maksimum 4 jadat paralelno. Ne smeat da jadat eden po eden.
  189.      *
  190.      * @throws RuntimeException
  191.      */
  192.     public void eat() throws RuntimeException {
  193.         log(ready.decrementWithMin(false), null);
  194.         log(eat.incrementWithMax(false), "jadenje");
  195.         Switcher.forceSwitch(15);
  196.         log(eat.decrementWithMin(false), null);
  197.  
  198.     }
  199.  
  200.     /**
  201.      * Se povikuva od gotvacot. Ne smee da se povika koga kazanot ne e prazen.
  202.      *
  203.      * @throws RuntimeException
  204.      */
  205.     public void cook() throws RuntimeException {
  206.         log(platesLeft.assertEquals(EMPTY_POT, 5,
  207.                 _5_NE_MOZE_DA_SE_GOTVI_VO_KAZAN_KOJ_NE_E_PRAZEN), null);
  208.         Switcher.forceSwitch(10);
  209.         platesLeft.setValue(POT_CAPACITY);
  210.     }
  211.  
  212.     @Override
  213.     public void finalize() {
  214.         if (eat.getMax() == 1) {
  215.             logException(new PointsException(10,
  216.                     _10_JADENJETO_NE_E_PARALELIZIRANO));
  217.         }
  218.     }
  219.  
  220. }
  221. abstract class AbstractState {
  222.  
  223.     /**
  224.      * Method called after threads ended their execution to validate the
  225.      * correctness of the scenario
  226.      */
  227.     public abstract void finalize();
  228.  
  229.     /**
  230.      * List of logged actions
  231.      */
  232.     private List<String> actions = new ArrayList<String>();
  233.  
  234.     /**
  235.      *
  236.      * @return if the current thread is instance of TemplateThread it is
  237.      *         returned, and otherwise null is returned
  238.      */
  239.     protected TemplateThread getThread() {
  240.         Thread current = Thread.currentThread();
  241.         if (current instanceof TemplateThread) {
  242.             TemplateThread t = (TemplateThread) current;
  243.             return t;
  244.         } else {
  245.             return null;
  246.         }
  247.     }
  248.  
  249.     /**
  250.      * Log this exception or action
  251.      *
  252.      * @param e
  253.      *            occurred exception (null if no exception)
  254.      * @param action
  255.      *            Description of the occurring action
  256.      */
  257.     public synchronized void log(PointsException e, String action) {
  258.         TemplateThread t = (TemplateThread) Thread.currentThread();
  259.         if (e != null) {
  260.             t.setException(e);
  261.             actions.add(t.toString() + "\t(e): " + e.getMessage());
  262.             throw e;
  263.         } else if (action != null) {
  264.             actions.add(t.toString() + "\t(a): " + action);
  265.         }
  266.     }
  267.  
  268.     /**
  269.      * Logging exceptions
  270.      *
  271.      * @param e
  272.      */
  273.     protected synchronized void logException(PointsException e) {
  274.         Thread t = Thread.currentThread();
  275.         if (e != null) {
  276.             if (t instanceof TemplateThread) {
  277.                 ((TemplateThread) t).setException(e);
  278.             }
  279.             TemplateThread.hasException = true;
  280.             actions.add("\t(e): " + e.getMessage());
  281.             throw e;
  282.         }
  283.     }
  284.  
  285.     /**
  286.      * Printing of the actions and exceptions that has occurred
  287.      */
  288.     public synchronized void printLog() {
  289.         System.out
  290.                 .println("Poradi konkurentnosta za pristap za pecatenje, mozno e nekoja od porakite da ne e na soodvetnoto mesto.");
  291.         System.out.println("Log na izvrsuvanje na akciite:");
  292.         System.out.println("=========================");
  293.         System.out.println("tip\tid\titer\takcija/error");
  294.         System.out.println("=========================");
  295.         for (String l : actions) {
  296.             System.out.println(l);
  297.         }
  298.     }
  299.  
  300.     /**
  301.      * Prints the status of the execution, with the exceptions that has occur
  302.      */
  303.     public void printStatus() {
  304.         try {
  305.             finalize();
  306.         } catch (Exception e) {
  307.             e.printStackTrace();
  308.         }
  309.         if (!TemplateThread.hasException) {
  310.             int poeni = 25;
  311.             if (PointsException.getTotalPoints() == 0) {
  312.                 System.out
  313.                         .println("Procesot e uspesno sinhroniziran. Osvoeni 25 poeni.");
  314.             } else {
  315.                 poeni -= PointsException.getTotalPoints();
  316.                 PointsException.printErrors();
  317.                 System.out.println("Maksimalni osvoeni poeni: " + poeni);
  318.             }
  319.  
  320.         } else {
  321.             System.out
  322.                     .println("Procesot ne e sinhroniziran spored uslovite na zadacata");
  323.             printLog();
  324.             System.out
  325.                     .println("====================================================");
  326.             PointsException.printErrors();
  327.             int total = (25 - PointsException.getTotalPoints());
  328.             if (total < 0) {
  329.                 total = 0;
  330.             }
  331.             System.out.println("Maksimum Poeni: " + total);
  332.         }
  333.  
  334.     }
  335. }
  336.  
  337. class PointsException extends RuntimeException {
  338.  
  339.     private static HashMap<String, PointsException> exceptions = new HashMap<String, PointsException>();
  340.     private int points;
  341.  
  342.     public PointsException(int points, String message) {
  343.         super(message);
  344.         this.points = points;
  345.         exceptions.put(message, this);
  346.     }
  347.  
  348.     public static int getTotalPoints() {
  349.         int sum = 0;
  350.         for (PointsException e : exceptions.values()) {
  351.             sum += e.getPoints();
  352.         }
  353.         return sum;
  354.     }
  355.  
  356.     public static void printErrors() {
  357.         if (!exceptions.isEmpty()) {
  358.             System.out.println("Gi imate slednite greski: ");
  359.             for (Map.Entry<String, PointsException> e : exceptions.entrySet()) {
  360.                 System.out.println(String.format("[%s] : (-%d)", e.getKey(), e
  361.                         .getValue().getPoints()));
  362.             }
  363.         }
  364.     }
  365.  
  366.     public int getPoints() {
  367.         return points;
  368.     }
  369. }
  370.  
  371. class Switcher {
  372.     private static final Random RANDOM = new Random();
  373.  
  374.     /*
  375.      * This method pauses the current thread i.e. changes its state to be
  376.      * Blocked. This should force thread switch if there are threads waiting
  377.      */
  378.     public static void forceSwitch(int range) {
  379.         try {
  380.             Thread.sleep(RANDOM.nextInt(range));
  381.         } catch (InterruptedException e) {
  382.         }
  383.     }
  384. }
  385.  
  386. abstract class TemplateThread extends Thread {
  387.  
  388.     static boolean hasException = false;
  389.     public int iteration = 0;
  390.     protected Exception exception = null;
  391.     int numRuns = 1;
  392.  
  393.     public TemplateThread(int numRuns) {
  394.         this.numRuns = numRuns;
  395.     }
  396.  
  397.     public abstract void execute() throws InterruptedException;
  398.  
  399.     @Override
  400.     public void run() {
  401.         try {
  402.             for (int i = 0; i < numRuns && !hasException; i++) {
  403.                 execute();
  404.                 iteration++;
  405.  
  406.             }
  407.         } catch (InterruptedException e) {
  408.             // Do nothing
  409.         } catch (Exception e) {
  410.             exception = e;
  411.             e.printStackTrace();
  412.             hasException = true;
  413.         }
  414.     }
  415.  
  416.     public void setException(Exception exception) {
  417.         this.exception = exception;
  418.         hasException = true;
  419.     }
  420.  
  421.     @Override
  422.     public String toString() {
  423.         Thread current = Thread.currentThread();
  424.         if (numRuns > 1) {
  425.             return String.format("[%d]%s\t%d\t%d", new Date().getTime(), ""
  426.                             + current.getClass().getSimpleName().charAt(0), getId(),
  427.                     iteration);
  428.         } else {
  429.             return String.format("[%d]%s\t%d\t", new Date().getTime(), ""
  430.                     + current.getClass().getSimpleName().charAt(0), getId());
  431.         }
  432.     }
  433. }
  434.  
  435. class BoundCounterWithRaceConditionCheck {
  436.  
  437.     private static final int RACE_CONDITION_POINTS = 25;
  438.     private static final String RACE_CONDITION_MESSAGE = "Race condition occured";
  439.  
  440.     private int value;
  441.     private Integer maxAllowed;
  442.     private Integer minAllowed;
  443.     private int maxErrorPoints;
  444.     private int minErrorPoints;
  445.     private String maxErrorMessage;
  446.     private String minErrorMessage;
  447.  
  448.     public static int raceConditionDefaultTime = 3;
  449.  
  450.     private int max;
  451.  
  452.     /**
  453.      *
  454.      * @param value
  455.      */
  456.     public BoundCounterWithRaceConditionCheck(int value) {
  457.         super();
  458.         this.value = value;
  459.         this.max = value;
  460.     }
  461.  
  462.     /**
  463.      *
  464.      * @param value
  465.      *            initial value
  466.      * @param maxAllowed
  467.      *            upper bound of the value
  468.      * @param maxErrorPoints
  469.      *            how many points are lost with the max value constraint
  470.      *            violation
  471.      * @param maxErrorMessage
  472.      *            message shown when the upper bound constrain is violated
  473.      * @param minAllowed
  474.      *            lower bound of the value
  475.      * @param minErrorPoints
  476.      *            how many points are lost with the min value constraint
  477.      *            violation
  478.      * @param minErrorMessage
  479.      *            message shown when the lower bound constrain is violated
  480.      */
  481.     public BoundCounterWithRaceConditionCheck(int value, Integer maxAllowed,
  482.                                               int maxErrorPoints, String maxErrorMessage, Integer minAllowed,
  483.                                               int minErrorPoints, String minErrorMessage) {
  484.         super();
  485.         this.value = value;
  486.         this.max = value;
  487.         this.maxAllowed = maxAllowed;
  488.         this.minAllowed = minAllowed;
  489.         this.maxErrorPoints = maxErrorPoints;
  490.         this.minErrorPoints = minErrorPoints;
  491.         this.maxErrorMessage = maxErrorMessage;
  492.         this.minErrorMessage = minErrorMessage;
  493.     }
  494.  
  495.     /**
  496.      *
  497.      * @return the maximum value of the integer variable that occurred at some
  498.      *         point of the execution
  499.      */
  500.     public int getMax() {
  501.         return max;
  502.     }
  503.  
  504.     /**
  505.      *
  506.      * @return the current value
  507.      */
  508.     public synchronized int getValue() {
  509.         return value;
  510.     }
  511.  
  512.     public synchronized void setValue(int value) {
  513.         this.value = value;
  514.     }
  515.  
  516.     /**
  517.      * Throws exception when the val is different than the value of the counter.
  518.      *
  519.      * @param val
  520.      * @param points
  521.      * @param errorMessage
  522.      * @return
  523.      */
  524.     public synchronized PointsException assertEquals(int val, int points,
  525.                                                      String errorMessage) {
  526.         if (this.value != val) {
  527.             PointsException e = new PointsException(points, errorMessage);
  528.             return e;
  529.         } else {
  530.             return null;
  531.         }
  532.     }
  533.  
  534.     public synchronized PointsException assertNotEquals(int val, int points,
  535.                                                         String errorMessage) {
  536.         if (this.value == val) {
  537.             PointsException e = new PointsException(points, errorMessage);
  538.             return e;
  539.         } else {
  540.             return null;
  541.         }
  542.     }
  543.  
  544.     /**
  545.      * Testing for race condition. NOTE: there are no guarantees that the race
  546.      * condition will be detected
  547.      *
  548.      * @return
  549.      */
  550.     public PointsException checkRaceCondition() {
  551.         return checkRaceCondition(raceConditionDefaultTime,
  552.                 RACE_CONDITION_MESSAGE);
  553.     }
  554.  
  555.     /**
  556.      * Testing for race condition. NOTE: there are no guarantees that the race
  557.      * condition will be detected, but higher the time argument is, the
  558.      * probability for race condition occurrence is higher
  559.      *
  560.      * @return
  561.      */
  562.     public PointsException checkRaceCondition(int time, String message) {
  563.         int val;
  564.  
  565.         synchronized (this) {
  566.             val = value;
  567.         }
  568.         Switcher.forceSwitch(time);
  569.         if (val != value) {
  570.             PointsException e = new PointsException(RACE_CONDITION_POINTS,
  571.                     message);
  572.             return e;
  573.         }
  574.         return null;
  575.  
  576.     }
  577.  
  578.     public PointsException incrementWithMax() {
  579.         return incrementWithMax(true);
  580.     }
  581.  
  582.     public PointsException incrementWithMax(boolean checkRaceCondition) {
  583.         if (checkRaceCondition) {
  584.             PointsException raceCondition = checkRaceCondition();
  585.             if (raceCondition != null) {
  586.                 return raceCondition;
  587.             }
  588.         }
  589.         synchronized (this) {
  590.             value++;
  591.  
  592.             if (value > max) {
  593.                 max = value;
  594.             }
  595.             if (maxAllowed != null) {
  596.                 if (value > maxAllowed) {
  597.                     PointsException e = new PointsException(maxErrorPoints,
  598.                             maxErrorMessage);
  599.                     return e;
  600.                 }
  601.             }
  602.         }
  603.  
  604.         return null;
  605.     }
  606.  
  607.     public PointsException decrementWithMin() {
  608.         return decrementWithMin(true);
  609.     }
  610.  
  611.     public PointsException decrementWithMin(boolean checkRaceCondition) {
  612.         if (checkRaceCondition) {
  613.             PointsException raceCondition = checkRaceCondition();
  614.             if (raceCondition != null) {
  615.                 return raceCondition;
  616.             }
  617.         }
  618.  
  619.         synchronized (this) {
  620.             value--;
  621.             if (minAllowed != null) {
  622.                 if (value < minAllowed) {
  623.                     PointsException e = new PointsException(minErrorPoints,
  624.                             minErrorMessage);
  625.                     return e;
  626.                 }
  627.             }
  628.         }
  629.         return null;
  630.     }
  631.  
  632. }
  633.  
  634. abstract class ProblemExecution {
  635.  
  636.     public static void start(HashSet<Thread> threads, AbstractState state)
  637.             throws Exception {
  638.  
  639.         startWithoutDeadlock(threads, state);
  640.  
  641.         checkDeadlock(threads, state);
  642.     }
  643.  
  644.     public static void startWithoutDeadlock(HashSet<Thread> threads,
  645.                                             AbstractState state) throws Exception {
  646.  
  647.         // start the threads
  648.         for (Thread t : threads) {
  649.             t.start();
  650.         }
  651.  
  652.         // wait threads to finish
  653.         for (Thread t : threads) {
  654.             t.join(1000);
  655.         }
  656.  
  657.     }
  658.  
  659.     private static void checkDeadlock(HashSet<Thread> threads,
  660.                                       AbstractState state) {
  661.         // check for deadlock
  662.         for (Thread t : threads) {
  663.             if (t.isAlive()) {
  664.                 t.interrupt();
  665.                 if (t instanceof TemplateThread) {
  666.                     TemplateThread tt = (TemplateThread) t;
  667.                     tt.setException(new PointsException(25, "DEADLOCK"));
  668.                 }
  669.             }
  670.         }
  671.  
  672.         // print the status
  673.         state.printStatus();
  674.     }
  675.  
  676. }
Add Comment
Please, Sign In to add comment