Dzok1517

KlizalsiteAtomici

Jan 13th, 2021
809
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package trinaestiprvi;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.concurrent.atomic.AtomicInteger;
  9.  
  10. import os.simulation.Application;
  11. import os.simulation.AutoCreate;
  12. import os.simulation.Container;
  13. import os.simulation.Item;
  14. import os.simulation.Operation;
  15. import os.simulation.Thread;
  16.  
  17. /*
  18.  * Data je simulacija rada Ledene šume u Dunavskom parku. Korisnici mogu dola-
  19.  * ziti bilo kada u toku radnog vremena i koristiti usluge klizališta. Prilikom
  20.  * ulaska korišćenje klizaljki je obavezno.
  21.  *
  22.  * Poznavajući kućni red, korisnici prilikom dolaska prvo iznajmljuju klizaljke,
  23.  * obuvaju ih i tek potom stupaju na stazu za klizanje. Takođe, prilikom odla-
  24.  * ska korisnici obuvaju svoju obuću, vraćaju klizaljke i tek potom odlaze.
  25.  *
  26.  * Ledena šuma se skoro otvorila i prve nedelje je velika gužva jer je većina
  27.  * mladih parova u gradu odlučila da se malo oproba na ledu. Svi parovi se sa-
  28.  * staju ispred ulaza na klizalište.
  29.  *
  30.  * Pomoću klasa iz paketa java.util.concurrent.atomic, sinhronizovati ove mlade
  31.  * parove tako da momak neće iznajmiti klizaljke i početi da kliza bez da sače-
  32.  * ka devojku, niti će se obuti i otići bez devojke. Analogno ni devojka neće
  33.  * uzeti klizaljke i klizati, ili otići iz dvorane bez da i momak uradi to isto.
  34.  *
  35.  * Dodatno 1
  36.  *
  37.  * Toplo vreme je učinilo da led na klizalištu ne bude dovoljno debeo i čvrst.
  38.  * Ovakav led može da izdrži najviše 300 kilograma težine. Sinhronizovati kli-
  39.  * zače tako da ne stupaju na klizalište ako bi pri tome pukao led.
  40.  *
  41.  * Uključiti animaciju kršenja uslova postavljanjem polja MAX_TEZINA na 300.
  42.  *
  43.  * Dodatno 2
  44.  *
  45.  * Umesto osnovnog problema, sinhronizovati klizače tako da dok klizaju momci,
  46.  * devojke ne stupaju na klizalište. Takođe, dok devojke klizaju, momci ne stu-
  47.  * paju na klizalište.
  48.  *
  49.  * Uključiti animaciju kršenja uslova postavljanjem polja JEDAN_POL na true.
  50.  *
  51.  * Dodatno 3
  52.  *
  53.  * Zbog velike gužve, klizalište ima samo 10 parova klizaljki na raspolaganju
  54.  * za iznajmljivanje.
  55.  *
  56.  * Uključiti animaciju kršenja uslova postavljanjem polja MAX_BR na 10.
  57.  *
  58.  * Dodatno 4
  59.  *
  60.  * Zbog velike gužve, klizalište ima ograničen broj klizaljki, tj. po 2 para od
  61.  * sledećih veličina: 28‐31, 32‐35, 36‐39, 40‐43, 44‐47, 48‐51 i 52‐55.
  62.  *
  63.  * Uključiti animaciju kršenja uslova postavljanjem polja MAX_CIPELA na 2.
  64.  *
  65.  * Dodatno 5
  66.  *
  67.  * Rešiti dodatne probleme 1, 2 i 4 zajedno.
  68.  *
  69.  * Dodatno 6
  70.  *
  71.  * Rešiti osnovni i dodatni problem 1 ako su tezine tipa double.
  72.  *
  73.  * Promeniti polje tezina na: private double tezina = randomDouble(...);
  74.  *
  75.  * Dodatno 7
  76.  *
  77.  * Rešiti osnovni tako da umesto u parovima, klizaci klizaju u grupama od tri:
  78.  * jedan momak i dve devojke ili jedna devojka i dva momka. Takodje u takvim
  79.  * grupama i odlaze sa klizalista.
  80.  */
  81. public class KlizalisteAtomici extends Application {
  82.     private class Pristup{
  83.        
  84.         private AtomicInteger brMomaka = new AtomicInteger(0);
  85.         private AtomicInteger brDevojaka = new AtomicInteger(0);
  86.                
  87.         private void sacekajMomka() {
  88.             brDevojaka.incrementAndGet();
  89.            
  90.             boolean ok;
  91.             do {
  92.                 int oldV = brMomaka.get();
  93.                 int newV = oldV - 1;
  94.                 ok = newV >= 0;
  95.                 if(ok) { ok = brMomaka.compareAndSet(oldV, newV);}
  96.                 else { Thread.yield(); }
  97.             }while(!ok);
  98.         }
  99.         private void sacekajDevojku() {
  100.             brMomaka.incrementAndGet();
  101.            
  102.             boolean ok;
  103.             do {
  104.                 int oldV = brDevojaka.get();
  105.                 int newV = oldV - 1;
  106.                 ok = newV >= 0;
  107.                 if(ok) { ok = brDevojaka.compareAndSet(oldV, newV);}
  108.                 else { Thread.yield(); }
  109.             }while(!ok);
  110.         }
  111.        
  112.         private AtomicInteger trenutnaKilazaNaledu = new AtomicInteger(0);
  113.         private AtomicInteger slobodnaKilaza = new AtomicInteger(MAX_TEZINA);
  114.        
  115.         private void staniNaLed(int tezina) {
  116.             boolean ok;
  117.             do {
  118.                 int oldV = slobodnaKilaza.get();
  119.                 int newV = oldV - tezina;
  120.                 ok = newV >= 0;
  121.                 if(ok) { ok = slobodnaKilaza.compareAndSet(oldV, newV);}
  122.                 else { Thread.yield(); }
  123.             }while(!ok);
  124.             trenutnaKilazaNaledu.addAndGet(tezina);
  125.         }
  126.         private void napustiLed(int tezina) {
  127.             boolean ok;
  128.             do {
  129.                 int oldV = trenutnaKilazaNaledu.get();
  130.                 int newV = oldV - tezina;
  131.                 ok = newV >= 0;
  132.                 if(ok) { ok = trenutnaKilazaNaledu.compareAndSet(oldV, newV);}
  133.                 else { Thread.yield(); }
  134.             }while(!ok);
  135.             slobodnaKilaza.addAndGet(tezina);
  136.            
  137.         }
  138.        
  139.         private AtomicInteger polAtomic = new AtomicInteger(0);
  140.         private AtomicInteger brKilzaca = new AtomicInteger(0);
  141.        
  142.         private void klizajSexRestricted(int pol) {
  143.             boolean ok;
  144.             do {
  145.                 int oldV = polAtomic.get();
  146.                 ok = oldV==0 || oldV == pol;
  147.                 if(ok) { ok = polAtomic.compareAndSet(oldV, pol);}
  148.                 else { Thread.yield(); }
  149.             }while(!ok);
  150.             brKilzaca.incrementAndGet();
  151.         }
  152.         private void zavrsiKlizanjeSexRestricted(int pol) {
  153.             boolean poslednji = false;
  154.             boolean ok;
  155.             do {
  156.                 int oldV = brKilzaca.get();
  157.                 int newV = oldV -1;
  158.                 ok = newV >= 0;
  159.                 if(ok) {
  160.                     ok = brKilzaca.compareAndSet(oldV, newV);
  161.                     if(newV == 0 )
  162.                         poslednji = true;
  163.                 }
  164.                 else { Thread.yield(); }
  165.             }while(!ok);
  166.             if(poslednji)
  167.                 polAtomic.set(0);
  168.         }
  169.        
  170.         private AtomicInteger paroviKlizaljki = new AtomicInteger(MAX_BR);
  171.         private AtomicInteger brojKlizaca = new AtomicInteger(0);
  172.        
  173.         private void stupiOgranicenoNa10Parova() {
  174.             boolean ok;
  175.             do {
  176.                 int oldV = paroviKlizaljki.get();
  177.                 int newV = oldV -1 ;
  178.                 ok =  newV >= 0;
  179.                 if(ok) { ok = paroviKlizaljki.compareAndSet(oldV, newV);}
  180.                 else { Thread.yield(); }
  181.             }while(!ok);
  182.             brojKlizaca.incrementAndGet();
  183.         }
  184.         private void napustiOgranicenoNa10Parova() {
  185.             boolean ok;
  186.             do {
  187.                 int oldV = brojKlizaca.get();
  188.                 int newV = oldV -1 ;
  189.                 ok =  newV >= 0;
  190.                 if(ok) { ok = brojKlizaca.compareAndSet(oldV, newV);}
  191.                 else { Thread.yield(); }
  192.             }while(!ok);
  193.             paroviKlizaljki.incrementAndGet();
  194.         }
  195.        
  196.         private AtomicInteger brKlizaljki2831 = new AtomicInteger(2);
  197.         private AtomicInteger brKlizaljki3235 = new AtomicInteger(2);
  198.         private AtomicInteger brKlizaljki3639 = new AtomicInteger(2);
  199.         private AtomicInteger brKlizaljki4043 = new AtomicInteger(2);
  200.         private AtomicInteger brKlizaljki4447 = new AtomicInteger(2);
  201.         private AtomicInteger brKlizaljki4851 = new AtomicInteger(2);
  202.         private AtomicInteger brKlizaljki5255 = new AtomicInteger(2);
  203.        
  204.         private AtomicInteger brKlizaljki2831NaStazi = new AtomicInteger(0);
  205.         private AtomicInteger brKlizaljki3235NaStazi = new AtomicInteger(0);
  206.         private AtomicInteger brKlizaljki3639NaStazi = new AtomicInteger(0);
  207.         private AtomicInteger brKlizaljki4043NaStazi = new AtomicInteger(0);
  208.         private AtomicInteger brKlizaljki4447NaStazi = new AtomicInteger(0);
  209.         private AtomicInteger brKlizaljki4851NaStazi = new AtomicInteger(0);
  210.         private AtomicInteger brKlizaljki5255NaStazi = new AtomicInteger(0);
  211.        
  212.         private AtomicInteger odrediAtomik(int brojKlizaljki) {
  213.             if(brojKlizaljki >= 28 && brojKlizaljki <= 31)
  214.                 return brKlizaljki2831;
  215.             else if(brojKlizaljki >= 32 && brojKlizaljki <= 35)
  216.                 return brKlizaljki3235;
  217.             else if(brojKlizaljki >= 36 && brojKlizaljki <= 39)
  218.                 return brKlizaljki3639;
  219.             else if(brojKlizaljki >= 40 && brojKlizaljki <= 43)
  220.                 return brKlizaljki4043;
  221.             else if(brojKlizaljki >= 44 && brojKlizaljki <= 47)
  222.                 return brKlizaljki4447;
  223.             else if(brojKlizaljki >= 48 && brojKlizaljki <= 51)
  224.                 return brKlizaljki4851;
  225.             else
  226.                 return brKlizaljki5255;
  227.         }
  228.        
  229.         private AtomicInteger odrediAtomikNaStazi(int brojKlizaljki) {
  230.             if(brojKlizaljki >= 28 && brojKlizaljki <= 31)
  231.                 return brKlizaljki2831NaStazi;
  232.             else if(brojKlizaljki >= 32 && brojKlizaljki <= 35)
  233.                 return brKlizaljki3235NaStazi;
  234.             else if(brojKlizaljki >= 36 && brojKlizaljki <= 39)
  235.                 return brKlizaljki3639NaStazi;
  236.             else if(brojKlizaljki >= 40 && brojKlizaljki <= 43)
  237.                 return brKlizaljki4043NaStazi;
  238.             else if(brojKlizaljki >= 44 && brojKlizaljki <= 47)
  239.                 return brKlizaljki4447NaStazi;
  240.             else if(brojKlizaljki >= 48 && brojKlizaljki <= 51)
  241.                 return brKlizaljki4851NaStazi;
  242.             else
  243.                 return brKlizaljki5255;
  244.         }
  245.        
  246.         private void uzmiKlizaljkeSaBrojem(int brojKlizaljki) {
  247.             boolean ok;
  248.             do {
  249.                 int oldV = (odrediAtomik(brojKlizaljki)).get();
  250.                 int newV = oldV -1 ;
  251.                 ok =  newV >= 0;
  252.                 if(ok) { ok = (odrediAtomik(brojKlizaljki)).compareAndSet(oldV, newV);}
  253.                 else { Thread.yield(); }
  254.             }while(!ok);
  255.             (odrediAtomikNaStazi(brojKlizaljki)).incrementAndGet();
  256.         }
  257.        
  258.         private void vratiKlizaljkeSaBrojem(int brojKlizaljki) {
  259.             boolean ok;
  260.             do {
  261.                 int oldV = (odrediAtomikNaStazi(brojKlizaljki)).get();
  262.                 int newV = oldV -1 ;
  263.                 ok =  newV >= 0;
  264.                 if(ok) { ok = (odrediAtomikNaStazi(brojKlizaljki)).compareAndSet(oldV, newV);}
  265.                 else { Thread.yield(); }
  266.             }while(!ok);
  267.             (odrediAtomik(brojKlizaljki)).incrementAndGet();
  268.         }
  269.     }
  270.     private Pristup pristup = new Pristup();
  271.     @AutoCreate
  272.     protected class Momak extends Thread {
  273.  
  274.         private int brojCipela = randomInt(38, 56);
  275.         private int tezina = randomInt(70, 100);
  276.  
  277.         @Override
  278.         protected void run() {
  279.            
  280.         //  pristup.sacekajDevojku();
  281.                 //pristup.stupiOgranicenoNa10Parova();
  282.             pristup.uzmiKlizaljkeSaBrojem(brojCipela);
  283.             obuvaSe();
  284.             //pristup.staniNaLed(tezina);
  285.     //pristup.klizajSexRestricted(1);
  286.             kliza();
  287.     //pristup.zavrsiKlizanjeSexRestricted(1);
  288.            
  289.         //  pristup.sacekajDevojku();
  290.             //pristup.napustiLed(tezina);
  291.            
  292.             izuvaSe();
  293.             pristup.vratiKlizaljkeSaBrojem(brojCipela);
  294.                 //pristup.napustiOgranicenoNa10Parova();
  295.            
  296.         }
  297.     }
  298.  
  299.     @AutoCreate
  300.     protected class Devojka extends Thread {
  301.  
  302.         private int brojCipela = randomInt(28, 46);
  303.         private int tezina = randomInt(60, 80);
  304.  
  305.         @Override
  306.         protected void run() {
  307.            
  308.         //  pristup.sacekajMomka();
  309.                 //pristup.stupiOgranicenoNa10Parova();
  310.             pristup.uzmiKlizaljkeSaBrojem(brojCipela);
  311.             obuvaSe();
  312.             //pristup.staniNaLed(tezina);
  313.     //pristup.klizajSexRestricted(2);
  314.             kliza();
  315.     //pristup.zavrsiKlizanjeSexRestricted(2);
  316.         //  pristup.sacekajMomka();
  317.             //pristup.napustiLed(tezina);
  318.            
  319.             izuvaSe();
  320.             pristup.vratiKlizaljkeSaBrojem(brojCipela);
  321.                 //pristup.napustiOgranicenoNa10Parova();
  322.            
  323.         }
  324.     }
  325.  
  326.     protected final int MAX_TEZINA = 0;
  327.     protected final int MAX_BR = 0;
  328.     protected final int MAX_CIPELA = 2;
  329.     protected final boolean JEDAN_POL = false;
  330.  
  331.     // ------------------- //
  332.     //    Sistemski deo    //
  333.     // ------------------- //
  334.     // Ne dirati kod ispod //
  335.     // ------------------- //
  336.  
  337.     protected final Container ulaz      = box("Улаз").color(NAVY);
  338.     protected final Container garderoba = box("Клизаљке").color(OLIVE);
  339.     protected final Container izlaz     = box("Клизаљке").color(OLIVE);
  340.     protected final Container dvorana   = box("Ледена дворана");
  341.     protected final Container main      = column(row(ulaz, garderoba, izlaz), dvorana);
  342.     protected final Operation momak     = duration("2±1").container(ulaz).name("Момак %d").text("Чека").color(AZURE);
  343.     protected final Operation devojka   = duration("2±1").container(ulaz).name("Девојка %d").text("Чека").color(ROSE);
  344.     protected final Operation obuvanje  = duration("4").text("Узима").container(garderoba).containerAfter(garderoba);
  345.     protected final Operation klizanje  = duration("6±2").text("Клиза").container(dvorana).containerAfter(dvorana).updateBefore(this::azuriraj);
  346.     protected final Operation izuvanje  = duration("4").text("Враћа").container(izlaz).containerAfter(izlaz).updateBefore(this::azuriraj);
  347.  
  348.     protected void obuvaSe() {
  349.         obuvanje.performUninterruptibly();
  350.     }
  351.  
  352.     protected void kliza() {
  353.         klizanje.performUninterruptibly();
  354.     }
  355.  
  356.     protected void izuvaSe() {
  357.         izuvanje.performUninterruptibly();
  358.     }
  359.  
  360.     protected void azuriraj(Item item) {
  361.         int br = 0;
  362.         int brM = 0;
  363.         int brD = 0;
  364.         double tezina = 0.0;
  365.         List<Integer> cipele = new ArrayList<>();
  366.         Map<Integer, Integer> grupe = new HashMap<>();
  367.         for (Momak momak : dvorana.getItems(Momak.class)) {
  368.             br += 1;
  369.             brM += 1;
  370.             tezina += momak.tezina;
  371.             cipele.add(momak.brojCipela);
  372.             grupe.compute(momak.brojCipela / 4, (k, v) -> v == null ? 1 : v + 1);
  373.         }
  374.         for (Devojka devojka : dvorana.getItems(Devojka.class)) {
  375.             br += 1;
  376.             brD += 1;
  377.             tezina += devojka.tezina;
  378.             cipele.add(devojka.brojCipela);
  379.             grupe.compute(devojka.brojCipela / 4, (k, v) -> v == null ? 1 : v + 1);
  380.         }
  381.         Collections.sort(cipele);
  382.         int max = grupe.values().stream().mapToInt(Integer::intValue).max().orElse(0);
  383.         boolean tezinaOk = MAX_TEZINA == 0 || tezina <= MAX_TEZINA;
  384.         boolean brOk = MAX_BR == 0 || br <= MAX_BR;
  385.         boolean cipeleOk = MAX_CIPELA == 0 || max <= MAX_CIPELA;
  386.         boolean polOk = !JEDAN_POL || brM == 0 || brD == 0;
  387.         StringBuilder builder = new StringBuilder();
  388.         if (MAX_BR != 0) {
  389.             builder.append(String.format("%d", br));
  390.         }
  391.         if (MAX_CIPELA != 0) {
  392.             if (builder.length() != 0) {
  393.                 builder.append("  ");
  394.             }
  395.             builder.append(String.format("%s", cipele));
  396.         }
  397.         if (MAX_TEZINA != 0) {
  398.             if (builder.length() != 0) {
  399.                 builder.append("  ");
  400.             }
  401.             builder.append(String.format("%4.2f kg", tezina));
  402.         }
  403.         dvorana.setText(builder.toString());
  404.         if (tezinaOk && brOk && cipeleOk && polOk) {
  405.             dvorana.setColor(SILVER);
  406.         } else {
  407.             dvorana.setColor(MAROON);
  408.         }
  409.     }
  410.  
  411.     @Override
  412.     protected void initialize() {
  413.         azuriraj(null);
  414.     }
  415.  
  416.     public static void main(String[] arguments) {
  417.         launch("Клизалиште");
  418.     }
  419. }
  420.  
RAW Paste Data