Advertisement
JovanPapi

[OS - lab3] Задача 2 - Barber

Mar 31st, 2019
630
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 18.49 KB | None | 0 0
  1. Задача 2
  2. Потребно е да го синхронизирате сценариото на работа на една берберница. Берберницата има само еден бербер кој спие се додека не се насоберат 5 клиенти. Кога ќе се насоберат 5 клиенти, петтиот го буди берберот и тој започнува да ги потстрижува. Штом берберот ќе ги потстриже сите клиенти што чекаат, тој повторно заспива.
  3.  
  4. Кога берберот е буден, тој најпрво повикува еден клиент да влезе во берберницата. Кога клиентот ќе биде присутен, започнува процесот на потстрижување. Откако клиентот е потстрижен, тој плаќа и ја напушта берберницата, по што може да влезе нареден клиент. Доколку нема нареден клиент, берберот заспива. Доколку берберот спие, клиентите треба да чекаат додека не се соберат 5 од нив, и петтиот треба да го разбуди берберот.
  5.  
  6. Во почетниот код кој е даден, дефинирани се класите Barber и Customer, кои ги симболизираат берберот и клиентите. Има само една инстанца од класата Barber кај која методот execute() се повикува онолку пати колку што има клиенти и повеќе инстанци од класата Customer во кои методот execute() се повикува само еднаш.
  7.  
  8. Вашата задача е да ги имплементирате методите execute() од класата Barber и Customer според претходно опшаното сценарио.
  9.  
  10. Во имплементацијата, можете да ги користите следните методи од веќе дефинираната променлива state:
  11.  
  12. state.customerArrived()
  13. Го симболизира пристигнувањето на клиент пред берберницата. Се повикува од клиентот, по неговото пристигнување.
  14. state.barberWakeUp()
  15. Го симболизира будењето на берберот. Се повикува од берберот кога тој се буди.
  16. Доколку берберот е веќе рабуден, повикот ќе фрли исклучок.
  17. state.barberCallCustomer()
  18. Го симболизира повикувањето на клиентот од страна на берберот. Се повикува кај берберот.
  19. Доколку нема пристигнато клиент, овој повик ќе фрли исклучок.
  20. state.customerEntry()
  21. Го симболизира влегувањето на клиентот во берберницата. Се повикува кај клиентот.
  22. Доколку нема пристигнато клиент, или нема повик од берберот, овој повик ќе фрли исклучок.
  23. state.cutHair()
  24. Го симболизира потстрижувањето на клиентот од страна на берберот. Се повикува кај берберот.
  25. Доколку нема присутен клиент во берберницата, овој повик ќе фрли исклучок.
  26. state.customerPay()
  27. Го симболизира плаќањето на клиентот и напуштањето на берберницата. Се повикува кај клиентот.
  28. state.barberGoToSleep()
  29. Го симболизира заспивањето на берберот, кога нема присутни клиенти. Се повикува кај берберот.
  30. Доколку берберот веќе спие или ако има клиенти што чекаат, овој повик ќе фрли исклучок.
  31. Претходно назначените методи служат за проверка на точноста на сценариото и не смеат да бидат променети и мораат да бидат повикани.
  32.  
  33. Вашата задача е да ги имплементирате методите Barber.execute()и Customer.execute() и init(). При имплементацијата, не смеете да додадете try-catch блок во нив. Потребните семафори, глобални променливи и променливи за состојбите на берберо ти клиентот треба да ги дефинирате самите.
  34.  
  35. Доколку имате грешка, ќе ја добиете пораката:
  36.  
  37. Procesot ne e sinhroniziran spored uslovite na zadacata
  38.  
  39. По што ќе ви се прикаже логот на повикување на акциите и настанатите грешки. Овој лог треба да ви послужи за увидување на тоа каде имате грешка во извршувањето на вашата задача.
  40.  
  41.  
  42.  
  43. package Zadaca2;
  44.  
  45. import java.util.ArrayList;
  46. import java.util.HashMap;
  47. import java.util.HashSet;
  48. import java.util.List;
  49. import java.util.Map;
  50. import java.util.Random;
  51. import java.util.Scanner;
  52. import java.util.concurrent.Semaphore;
  53.  
  54. /**
  55.  *
  56.  * @author ristes
  57.  */
  58. public class TemplateNumRunsAndNumInstances {
  59.  
  60.     //TODO: definirajte gi semaforite i ostanatite promenlivi ovde (mora site da se static)
  61.     static Semaphore canEnter;
  62.     static int numberClients;
  63.     static Semaphore imCut;
  64.     static Semaphore permissionToWakeUp;
  65.     static Semaphore readyToCutTheBalls;
  66.     static Semaphore canPay;
  67.     static Semaphore isSleeping;
  68.    
  69.     /**
  70.      * Metod koj treba da gi inicijalizira vrednostite na semaforite i
  71.      * ostanatite promenlivi za sinhronizacija.
  72.      *
  73.      *
  74.      * TODO: da se implementira
  75.      *
  76.      */
  77.     public static void init(int numBarbers) {
  78.          numberClients = 0;
  79.          canEnter = new Semaphore(0);
  80.          imCut = new Semaphore(0);
  81.          permissionToWakeUp = new Semaphore(0);
  82.          readyToCutTheBalls = new Semaphore(0);
  83.          canPay = new Semaphore(0);
  84.          isSleeping = new Semaphore(1);
  85.        
  86.        
  87.     }
  88.  
  89.     static class Barber extends TemplateThread {
  90.  
  91.         public int barberId;
  92.  
  93.         public Barber(int numRuns, int barberId) {
  94.             super(numRuns);
  95.             this.barberId = barberId;
  96.         }
  97.  
  98.         /**
  99.          * Da se implementira odnesuvanjeto na berberot spored baranjeto na
  100.          * zadacata.
  101.          *
  102.          *
  103.          * TODO: da se implementira
  104.          *
  105.          */
  106.         public void execute() throws InterruptedException {
  107.        
  108.             permissionToWakeUp.acquire();
  109.             state.barberWakeUp();
  110.            
  111.             synchronized(TemplateNumRunsAndNumInstances.class) {
  112.                
  113.                 state.barberCallCustomer();
  114.  
  115.                 canEnter.release();
  116.                
  117.             }    
  118.            
  119.             readyToCutTheBalls.acquire();
  120.             state.cutHair();
  121.            
  122.             imCut.release();
  123.            
  124.            canPay.acquire();
  125.            if(numberClients == 0) {
  126.                 isSleeping.release();
  127.                state.barberGoToSleep();
  128.            }
  129.  
  130.         }
  131.     }
  132.  
  133.     static class Consumer extends TemplateThread {
  134.  
  135.         public Consumer(int numRuns) {
  136.             super(numRuns);
  137.         }
  138.  
  139.         /**
  140.          * Da se implementira odnesuvanjeto na ucesnikot spored uslovite na
  141.          * zadacata.
  142.          */
  143.         public void execute() throws InterruptedException {
  144.  
  145.             state.customerArrived();
  146.            
  147.             synchronized(TemplateNumRunsAndNumInstances.class) {
  148.                 numberClients++;
  149.                
  150.                 if(numberClients == 5) {
  151.                     isSleeping.acquire();
  152.                     permissionToWakeUp.release();
  153.                 }
  154.             }
  155.            
  156.             canEnter.acquire();
  157.             state.customerEntry();
  158.        
  159.             readyToCutTheBalls.release();
  160.            
  161.             imCut.acquire();
  162.            
  163.             canPay.release();
  164.             state.customerPay();
  165.             synchronized(TemplateNumRunsAndNumInstances.class) {
  166.                 numberClients--;
  167.             }
  168.  
  169.         }
  170.     }
  171.     //<editor-fold defaultstate="collapsed" desc="This is the template code" >
  172.     static State state;
  173.  
  174.     static class State {
  175.  
  176.         private static final Random RANDOM = new Random();
  177.         private static final int RANDOM_RANGE = 5;
  178.         private final int numBarbers;
  179.         private boolean barberWaked[];
  180.  
  181.         public State(int numBarbers) {
  182.             this.numBarbers = numBarbers;
  183.             barberWaked = new boolean[numBarbers];
  184.         }
  185.         private int arrivedCustomers = 0;
  186.         private int calledCustomers = 0;
  187.         private int maxCuttings = 0;
  188.         private int numCuttings = 0;
  189.  
  190.         public synchronized void customerArrived() throws RuntimeException {
  191.             log(null, "customer arrived");
  192.             arrivedCustomers++;
  193.         }
  194.  
  195.         public synchronized void barberWakeUp() throws RuntimeException {
  196.             Barber b = (Barber) Thread.currentThread();
  197.             if (barberWaked[b.barberId]) {
  198.                 PointsException e = new PointsException(5, "Berberot e veke buden i nema potreba da se razbudi.");
  199.                 log(e, null);
  200.             } else {
  201.                 log(null, "the barber is waked up");
  202.                 barberWaked[b.barberId] = true;
  203.             }
  204.         }
  205.  
  206.         public synchronized void barberCallCustomer() throws RuntimeException {
  207.             log(null, "the barber calls the customer");
  208.             if (arrivedCustomers <= 0) {
  209.                 PointsException e = new PointsException(5, "Brojot na klienti koi cekaat e 0 i nema koj da bide povikan.");
  210.                 log(e, null);
  211.             }
  212.             calledCustomers++;
  213.         }
  214.  
  215.         public synchronized void customerEntry() throws RuntimeException {
  216.             log(null, "customer sits in the chair");
  217.             if (arrivedCustomers <= 0) {
  218.                 PointsException e = new PointsException(5, "Brojot na klienti koi cekaat e 0 i nema koj da vleze.");
  219.                 log(e, null);
  220.             }
  221.             if (calledCustomers <= 0) {
  222.                 PointsException e = new PointsException(5, "Nema povikano klient i ne moze da vleze.");
  223.                 log(e, null);
  224.             }
  225.             arrivedCustomers--;
  226.             calledCustomers--;
  227.  
  228.             numCuttings++;
  229.         }
  230.  
  231.         public void cutHair() throws RuntimeException {
  232.             synchronized (this) {
  233.                 if (numCuttings <= 0) {
  234.                     PointsException e = new PointsException(5, "Nema prisuten klient za potstrizuvanje");
  235.                     log(e, null);
  236.                 }
  237.  
  238.                 log(null, "berber cuts the customer hair");
  239.             }
  240.             try {
  241.                 int r;
  242.                 synchronized (this) {
  243.                     r = RANDOM.nextInt(RANDOM_RANGE);
  244.                 }
  245.                 Thread.sleep(r);
  246.             } catch (Exception e) {
  247.                 //do nothing
  248.             }
  249.             synchronized (this) {
  250.                 if (numCuttings <= 0) {
  251.                     PointsException e = new PointsException(5, "Brojot na klienti koi se strizat e 0 i nema koj da izleze.");
  252.                     log(e, null);
  253.                 }
  254.                 numCuttings--;
  255.             }
  256.  
  257.         }
  258.  
  259.         public synchronized void customerPay() throws RuntimeException {
  260.             log(null, "customer is paying and leaving the shop");
  261.  
  262.  
  263.         }
  264.  
  265.         public synchronized void barberGoToSleep() throws RuntimeException {
  266.             Barber b = (Barber) Thread.currentThread();
  267.             if (!barberWaked[b.barberId]) {
  268.                 PointsException e = new PointsException(5, "Berberite veke spijat i ne moze da se prezaspijat.");
  269.                 log(e, null);
  270.             }
  271.             if (arrivedCustomers > 0) {
  272.                 PointsException e = new PointsException(5, "Seuste ima klienti koi cekaat i berberot ne moze da odi na spienje.");
  273.                 log(e, null);
  274.             }
  275.             log(null, "all barbers go to sleap");
  276.             barberWaked[b.barberId] = false;
  277.         }
  278.         private List<String> actions = new ArrayList<String>();
  279.         private List<PointsException> exceptions = new ArrayList<PointsException>();
  280.  
  281.         private synchronized void log(PointsException e, String action) {
  282.             TemplateThread t = (TemplateThread) Thread.currentThread();
  283.             if (e == null) {
  284.                 actions.add(t.toString() + "\t(a): " + action);
  285.             } else {
  286.                 t.setException(e);
  287.                 actions.add(t.toString() + "\t(e): " + e.getMessage());
  288.             }
  289.         }
  290.  
  291.         public synchronized void printLog() {
  292.             System.out.println("Poradi konkurentnosta za pristap za pecatenje, mozno e nekoja od porakite da ne e na soodvetnoto mesto.");
  293.             System.out.println("Log na izvrsuvanje na akciite:");
  294.             System.out.println("=========================");
  295.             System.out.println("tip\tid\titer\takcija/error");
  296.             System.out.println("=========================");
  297.             for (String l : actions) {
  298.                 System.out.println(l);
  299.             }
  300.         }
  301.  
  302.         public void printStatus() {
  303.             if (!TemplateThread.hasException) {
  304.                 int poeni = 25;
  305.                 if (PointsException.getTotalPoints() == 0) {
  306.                     System.out.println("Procesot e uspesno sinhroniziran. Osvoeni 25 poeni.");
  307.                 } else {
  308.                     poeni -= PointsException.getTotalPoints();
  309.                     PointsException.printErrors();
  310.                     System.out.println("Osvoeni poeni: " + poeni);
  311.                 }
  312.  
  313.             } else {
  314.                 System.out.println("Procesot ne e sinhroniziran spored uslovite na zadacata");
  315.                 printLog();
  316.                 System.out.println("====================================================");
  317.                 PointsException.printErrors();
  318.                 System.out.println("Maksimum Poeni: " + (25 - PointsException.getTotalPoints()));
  319.             }
  320.  
  321.         }
  322.     }
  323.  
  324.     abstract static class TemplateThread extends Thread {
  325.  
  326.         static boolean hasException = false;
  327.         int numRuns = 1;
  328.         public int iteration = 0;
  329.         private Exception exception = null;
  330.  
  331.         public TemplateThread(int numRuns) {
  332.             this.numRuns = numRuns;
  333.         }
  334.  
  335.         abstract void execute() throws InterruptedException;
  336.  
  337.         @Override
  338.         public void run() {
  339.             try {
  340.                 for (int i = 0; i < numRuns && !hasException; i++) {
  341.                     execute();
  342.                     iteration++;
  343.  
  344.                 }
  345.             } catch (InterruptedException e) {
  346.                 // Do nothing
  347.             } catch (Exception e) {
  348.                 exception = e;
  349.                 hasException = true;
  350.             }
  351.         }
  352.  
  353.         public void setException(Exception exception) {
  354.             this.exception = exception;
  355.             hasException = true;
  356.         }
  357.  
  358.         @Override
  359.         public String toString() {
  360.             Thread current = Thread.currentThread();
  361.             if (numRuns > 1) {
  362.                 return String.format("%s\t%d\t%d", "" + current.getClass().getSimpleName().charAt(0), getId(), iteration);
  363.             } else {
  364.                 return String.format("%s\t%d\t", "" + current.getClass().getSimpleName().charAt(0), getId());
  365.             }
  366.         }
  367.     }
  368.  
  369.     static class PointsException extends RuntimeException {
  370.  
  371.         private static HashMap<String, PointsException> exceptions = new HashMap<String, PointsException>();
  372.         private int points;
  373.  
  374.         public PointsException(int points, String message) {
  375.             super(message);
  376.             this.points = points;
  377.             exceptions.put(message, this);
  378.         }
  379.  
  380.         public static int getTotalPoints() {
  381.             int sum = 0;
  382.             for (PointsException e : exceptions.values()) {
  383.                 sum += e.getPoints();
  384.             }
  385.             return sum;
  386.         }
  387.  
  388.         public static void printErrors() {
  389.             System.out.println("Gi imate slednite greski: ");
  390.             for (Map.Entry<String, PointsException> e : exceptions.entrySet()) {
  391.                 System.out.println(String.format("[%s] : (-%d)", e.getKey(), e.getValue().getPoints()));
  392.             }
  393.         }
  394.  
  395.         public int getPoints() {
  396.             return points;
  397.         }
  398.     }
  399.  
  400.     public static void main(String[] args) {
  401.         try {
  402.             start();
  403.         } catch (Exception ex) {
  404.             ex.printStackTrace();
  405.         }
  406.     }
  407.  
  408.     public static void start() throws Exception {
  409.         Scanner s = new Scanner(System.in);
  410.         int brBarbers = s.nextInt();
  411.         int brKonzumeri = s.nextInt();
  412.         int numBarberRuns = s.nextInt();
  413.         int numCustomerRuns = s.nextInt();
  414.         init(brBarbers);
  415.  
  416.         state = new State(brBarbers);
  417.         HashSet<Thread> threads = new HashSet<Thread>();
  418.  
  419.         for (int i = 0; i < brBarbers; i++) {
  420.             Barber prod = new Barber(numBarberRuns, i);
  421.             threads.add(prod);
  422.             prod.start();
  423.             Consumer c = new Consumer(numCustomerRuns);
  424.             threads.add(c);
  425.             c.start();
  426.         }
  427.  
  428.         for (int i = 0; i < brKonzumeri / 2 - brBarbers; i++) {
  429.             Consumer c = new Consumer(numCustomerRuns);
  430.             threads.add(c);
  431.             c.start();
  432.         }
  433.         try {
  434.             Thread.sleep(50);
  435.         } catch (Exception e) {
  436.             //do nothing
  437.         }
  438.         for (int i = 0; i < brKonzumeri / 2; i++) {
  439.             Consumer c = new Consumer(numCustomerRuns);
  440.             threads.add(c);
  441.             c.start();
  442.         }
  443.  
  444.  
  445.         for (Thread t : threads) {
  446.             t.join(1000);
  447.         }
  448.  
  449.         for (Thread t : threads) {
  450.             if (t.isAlive()) {
  451.                 t.interrupt();
  452.             }
  453.         }
  454.  
  455.         state.printStatus();
  456.     }
  457.     //</editor-fold>
  458. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement