Crazy

Музички бенд

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