Advertisement
JovanPapi

[OS - Ispitna] Music Band

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