<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="sr">
	<id>https://siwiki.rs/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ralepop</id>
	<title>SI Wiki - Кориснички доприноси [sr]</title>
	<link rel="self" type="application/atom+xml" href="https://siwiki.rs/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ralepop"/>
	<link rel="alternate" type="text/html" href="https://siwiki.rs/wiki/%D0%9F%D0%BE%D1%81%D0%B5%D0%B1%D0%BD%D0%BE:%D0%94%D0%BE%D0%BF%D1%80%D0%B8%D0%BD%D0%BE%D1%81%D0%B8/Ralepop"/>
	<updated>2026-07-21T14:26:45Z</updated>
	<subtitle>Кориснички доприноси</subtitle>
	<generator>MediaWiki 1.39.8</generator>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%88%D0%B0%D0%BD%D1%83%D0%B0%D1%80_2023&amp;diff=8395</id>
		<title>КДП/Јануар 2023</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%88%D0%B0%D0%BD%D1%83%D0%B0%D1%80_2023&amp;diff=8395"/>
		<updated>2026-06-20T08:05:32Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: /* {{категорија|2. задатак|Монитори}} */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}&lt;br /&gt;
&#039;&#039;&#039;Испит у јануарском испитном року 2023. године&#039;&#039;&#039; одржан је 18. јанаура. Поставка је доступна на [https://rti.etf.bg.ac.rs/rti/ir3kdp/rokovi/2223/IR3KDP_2023_jan.pdf страници предмета].&lt;br /&gt;
&lt;br /&gt;
== {{категорија|1. задатак|Семафори}} ==&lt;br /&gt;
{{делимично решено}}&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Имплементирати и објасните основну разлику и разлоге за постојање те разлике између имплементација бафера коначног капацитета (&amp;lt;code&amp;gt;bounded buffer&amp;lt;/code&amp;gt;) за случајеве 1 произвођач и 1 потрошач, као и M произвођача и N потрошача помоћу семафора. У складу са објашњењем, прикажите разлике и за случајеве M произвођача и 1 потрошач, као и 1 произвођач и N потрошача.&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1 произвођач и 1 потрошач&lt;br /&gt;
typeT buff[n];&lt;br /&gt;
int front = 0, rear = 0;&lt;br /&gt;
sem empty = n, full = 0;&lt;br /&gt;
// empty се користи као број празних места, а full као број попуњених места у баферу&lt;br /&gt;
&lt;br /&gt;
process Producer{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //произведи податак&lt;br /&gt;
  wait(empty); //чекај да бафер има празних места&lt;br /&gt;
  buf[rear] = data; rear = (rear + 1)%n;&lt;br /&gt;
  signal(full); //попуни једно место у баферу&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process Consumer{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //потроши податак&lt;br /&gt;
  wait(full); //чекај да бафер није празан&lt;br /&gt;
  res = buf[front]; front = (front + 1)%n;&lt;br /&gt;
  signal(empty); //ослободи једно место у баферу&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//За M произвођача и N потрошача потребан нам је још један пар семафора - да се осигура да ће само један произвођач убацивати (deposit) у бафер, ерго да ће само један потрошач узимати (fetch) из бафера у било ком тренутку&lt;br /&gt;
typeT buff[n]; const M = ..., N = ...;&lt;br /&gt;
int front = 0, rear = 0;&lt;br /&gt;
sem empty = n, full = 0;&lt;br /&gt;
sem mutexD = 1, mutexF = 1; // за међусобно искључивање током deposit и fetch&lt;br /&gt;
&lt;br /&gt;
process Producer[i = 1 to M]{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //произведи податак&lt;br /&gt;
  wait(mutexD); wait(empty); //чекај да сам једини који убацује у бафер и да бафер има празних места&lt;br /&gt;
  buf[rear] = data; rear = (rear + 1)%n;&lt;br /&gt;
  signal(mutexD); signal(full); //допусти да неки други поризвођач убацује у бафер и попуни једно место у баферу&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process Consumer[i = 1 to N]{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //потроши податак&lt;br /&gt;
  wait(mutexF); wait(full);&lt;br /&gt;
  res = buf[front]; front = (front + 1)%n;&lt;br /&gt;
  signal(mutexF); signal(empty);&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//За случај M произвођача и 1 потрошач није потребан семафор mutexF јер не постоји више потрошача који желе да узимају из бафера. Аналогно је за 1 произвођач и N потрошача.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== {{категорија|2. задатак|Монитори}} ==&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Аутомобили који долазе са севера и југа морају да пређу реку преко неког старог моста (&amp;lt;code&amp;gt;Old Bridge problem&amp;lt;/code&amp;gt;). На мосту постоји само једна возна трака, па сви аутомобили на мосту морају да се крећу у истом смеру. Због оптерећења моста које мост може да поднесе, број аутомобила који се налазе на мосту не сме да пређе K (K &amp;gt; 0). Написати монитор са &amp;lt;code&amp;gt;signal and continue&amp;lt;/code&amp;gt; дисциплином који решава дати проблем.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
const K = ...;&lt;br /&gt;
&lt;br /&gt;
monitor Bridge {&lt;br /&gt;
  int waitingS = 0, waitingN = 0;&lt;br /&gt;
  int cnt = 0;  // тренутан број аутића на мосту&lt;br /&gt;
  int dir = 0;  // 0 - нико не чека и нико није на мосту, 1 - тренутно прелазе&lt;br /&gt;
                // кола са севера, 2 - са југа&lt;br /&gt;
  cond goN, goS;&lt;br /&gt;
&lt;br /&gt;
  void EnterNorth() {&lt;br /&gt;
    waitingN++;&lt;br /&gt;
    // Чекај ако прелазе кола са југа или ако је на мосту већ К аутића&lt;br /&gt;
    while (dir == 2 || cnt == K) {&lt;br /&gt;
      wait(goN);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    waitingN--;&lt;br /&gt;
    dir = 1;&lt;br /&gt;
    cnt++;&lt;br /&gt;
&lt;br /&gt;
    // Ако има још места на мосту и има аутића који чекају - сигнализирај&lt;br /&gt;
    if (cnt &amp;lt; K &amp;amp;&amp;amp; goN.queue) {&lt;br /&gt;
      signal(goN);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void ExitNorth() {&lt;br /&gt;
    cnt--;&lt;br /&gt;
    if (cnt == 0) {        // мост је слободан&lt;br /&gt;
      if (waitingS &amp;gt; 0) {  // прво проверава супротан смер и препушта мост њима ако неко чека&lt;br /&gt;
        dir = 2;&lt;br /&gt;
        signal(goS);&lt;br /&gt;
      } else if (waitingN &amp;gt; 0) {&lt;br /&gt;
        dir = 1;&lt;br /&gt;
        signal(goN);&lt;br /&gt;
      } else {&lt;br /&gt;
        dir = 0;&lt;br /&gt;
      }&lt;br /&gt;
    } else {  // Мост није празан, ако неко чека на северу пропуштамо&lt;br /&gt;
      if (waitingN &amp;gt; 0) {&lt;br /&gt;
        signal(goN);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void EnterSouth() {&lt;br /&gt;
    waitingS++;&lt;br /&gt;
    while (dir == 1 || cnt == K) {&lt;br /&gt;
      wait(goS);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    waitingS--;&lt;br /&gt;
    dir = 2;&lt;br /&gt;
    cnt++;&lt;br /&gt;
&lt;br /&gt;
    if (cnt &amp;lt; K &amp;amp;&amp;amp; goS.queue) {&lt;br /&gt;
      signal(goS);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void ExitSouth() {&lt;br /&gt;
    cnt--;&lt;br /&gt;
    if (cnt == 0) {&lt;br /&gt;
      if (waitingN &amp;gt; 0) {&lt;br /&gt;
        dir = 1;&lt;br /&gt;
        signal(goN);&lt;br /&gt;
      } else if (waitingS &amp;gt; 0) {&lt;br /&gt;
        dir = 2;&lt;br /&gt;
        signal(goS);&lt;br /&gt;
      } else {&lt;br /&gt;
        dir = 0;&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      if (waitingS &amp;gt; 0) {&lt;br /&gt;
        signal(goS);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== {{категорија|3. задатак|CSP}} ==&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Решити проблем читалаца и писаца користећи &#039;&#039;CSP&#039;&#039;. Решење треба да обезбеди да када стигне захтев од писца за тражење дозволе за започињање писања не треба прихватати захтеве за започињање било од читалаца било од писаца док тај писац не заврши са писањем.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
[reader(i:1..N)::READER || writer(i:1..M)::WRITER || conductor::CONDUCTOR]&lt;br /&gt;
&lt;br /&gt;
READER :: *[&lt;br /&gt;
    conductor!request&lt;br /&gt;
    conductor!pass&lt;br /&gt;
    // reading&lt;br /&gt;
    conductor!done&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
WRITER :: *[&lt;br /&gt;
    conductor!request&lt;br /&gt;
    conductor!pass&lt;br /&gt;
    // writing&lt;br /&gt;
    conductor!done&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
CONDUCTOR :: [&lt;br /&gt;
    read_count: integer = 0&lt;br /&gt;
    write_count: integer = 0&lt;br /&gt;
    queue: (0..C) integer&lt;br /&gt;
    who: (0..C) char&lt;br /&gt;
    head: integer = 0&lt;br /&gt;
    tail: integer = 0&lt;br /&gt;
    *[&lt;br /&gt;
        head == tail, write_count == 0, (i:1..N) reader(i)?request -&amp;gt;&lt;br /&gt;
            reader(i)!pass&lt;br /&gt;
            read_count++&lt;br /&gt;
        □&lt;br /&gt;
        head == tail, write_count == 0, read_count == 0, (i:1..M) writer(i)?request -&amp;gt;&lt;br /&gt;
            writer(i)!pass&lt;br /&gt;
            write_count++&lt;br /&gt;
        □&lt;br /&gt;
        (head + 1) % N != tail, write_count + read_count != 0, (i:1..N) reader(i)?request -&amp;gt;&lt;br /&gt;
            queue(head) = i&lt;br /&gt;
            who(head) = &#039;r&#039;&lt;br /&gt;
            head = (head + 1) % N&lt;br /&gt;
        □&lt;br /&gt;
        (head + 1) % N != tail, write_count + read_count != 0, (i:1..M) writer(i)?request -&amp;gt;&lt;br /&gt;
            queue(head) = i&lt;br /&gt;
            who(head) = &#039;w&#039;&lt;br /&gt;
            head = (head + 1) % N&lt;br /&gt;
        □&lt;br /&gt;
        read_count == 1, (i:1..N) reader(i)?done -&amp;gt;&lt;br /&gt;
            read_count--&lt;br /&gt;
            *[&lt;br /&gt;
                head != tail, write_count == 0, who[tail] == &#039;r&#039; -&amp;gt;&lt;br /&gt;
                    reader(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    read_count++&lt;br /&gt;
                □&lt;br /&gt;
                head != tail, write_count == 0, read_count == 0, who[tail] == &#039;w&#039; -&amp;gt;&lt;br /&gt;
                    writer(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    write_count++&lt;br /&gt;
            ]&lt;br /&gt;
        □&lt;br /&gt;
        read_count != 1, (i:1..N) reader(i)?done -&amp;gt;&lt;br /&gt;
            read_count--&lt;br /&gt;
        □&lt;br /&gt;
        (i:1..M) writer(i)?done -&amp;gt;&lt;br /&gt;
            write_count--&lt;br /&gt;
            *[&lt;br /&gt;
                head != tail, write_count == 0, who[tail] == &#039;r&#039; -&amp;gt;&lt;br /&gt;
                    reader(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    read_count++&lt;br /&gt;
                □&lt;br /&gt;
                head != tail, write_count == 0, read_count == 0, who[tail] == &#039;w&#039; -&amp;gt;&lt;br /&gt;
                    writer(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    write_count++&lt;br /&gt;
            ]&lt;br /&gt;
    ]&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== {{категорија|4. задатак|C-Linda}} ==&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Трајект за превоз возила превози возила са обале на обалу. Трајект поседује M трака од којих свака има N позиција које су линеарно постављене једна иза друге. Возило заузима једну позицију. Возило приликом доласка стаје у ред за случајно изабрану траку и чека на укрцавање. Нема могућности за престројавањем. Возила улазе у своју траку једно по једно по редоследу у којем чекају у траци, док на трајекту има места. Када је пун, трајект започиње превоз возила на другу обалу. На другој обали возила се искрцавају из своје траке у редоследу супротном од редоследа у којем су се укрцала у своју траку. Када се сва возила искрцају, празан трајект се враћа на почетну обалу. Користећи &#039;&#039;C-Linda&#039;&#039; написати програм који решава овај проблем.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категорија:КДП]]&lt;br /&gt;
[[Категорија:Рокови]]&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%88%D0%B0%D0%BD%D1%83%D0%B0%D1%80_2023&amp;diff=8394</id>
		<title>КДП/Јануар 2023</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%88%D0%B0%D0%BD%D1%83%D0%B0%D1%80_2023&amp;diff=8394"/>
		<updated>2026-06-20T08:00:01Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: Dodate dve zasebne uslovne promenljive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}&lt;br /&gt;
&#039;&#039;&#039;Испит у јануарском испитном року 2023. године&#039;&#039;&#039; одржан је 18. јанаура. Поставка је доступна на [https://rti.etf.bg.ac.rs/rti/ir3kdp/rokovi/2223/IR3KDP_2023_jan.pdf страници предмета].&lt;br /&gt;
&lt;br /&gt;
== {{категорија|1. задатак|Семафори}} ==&lt;br /&gt;
{{делимично решено}}&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Имплементирати и објасните основну разлику и разлоге за постојање те разлике између имплементација бафера коначног капацитета (&amp;lt;code&amp;gt;bounded buffer&amp;lt;/code&amp;gt;) за случајеве 1 произвођач и 1 потрошач, као и M произвођача и N потрошача помоћу семафора. У складу са објашњењем, прикажите разлике и за случајеве M произвођача и 1 потрошач, као и 1 произвођач и N потрошача.&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// 1 произвођач и 1 потрошач&lt;br /&gt;
typeT buff[n];&lt;br /&gt;
int front = 0, rear = 0;&lt;br /&gt;
sem empty = n, full = 0;&lt;br /&gt;
// empty се користи као број празних места, а full као број попуњених места у баферу&lt;br /&gt;
&lt;br /&gt;
process Producer{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //произведи податак&lt;br /&gt;
  wait(empty); //чекај да бафер има празних места&lt;br /&gt;
  buf[rear] = data; rear = (rear + 1)%n;&lt;br /&gt;
  signal(full); //попуни једно место у баферу&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process Consumer{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //потроши податак&lt;br /&gt;
  wait(full); //чекај да бафер није празан&lt;br /&gt;
  res = buf[front]; front = (front + 1)%n;&lt;br /&gt;
  signal(empty); //ослободи једно место у баферу&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//За M произвођача и N потрошача потребан нам је још један пар семафора - да се осигура да ће само један произвођач убацивати (deposit) у бафер, ерго да ће само један потрошач узимати (fetch) из бафера у било ком тренутку&lt;br /&gt;
typeT buff[n]; const M = ..., N = ...;&lt;br /&gt;
int front = 0, rear = 0;&lt;br /&gt;
sem empty = n, full = 0;&lt;br /&gt;
sem mutexD = 1, mutexF = 1; // за међусобно искључивање током deposit и fetch&lt;br /&gt;
&lt;br /&gt;
process Producer[i = 1 to M]{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //произведи податак&lt;br /&gt;
  wait(mutexD); wait(empty); //чекај да сам једини који убацује у бафер и да бафер има празних места&lt;br /&gt;
  buf[rear] = data; rear = (rear + 1)%n;&lt;br /&gt;
  signal(mutexD); signal(full); //допусти да неки други поризвођач убацује у бафер и попуни једно место у баферу&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
process Consumer[i = 1 to N]{&lt;br /&gt;
  while(true){&lt;br /&gt;
  ... //потроши податак&lt;br /&gt;
  wait(mutexF); wait(full);&lt;br /&gt;
  res = buf[front]; front = (front + 1)%n;&lt;br /&gt;
  signal(mutexF); signal(empty);&lt;br /&gt;
  ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//За случај M произвођача и 1 потрошач није потребан семафор mutexF јер не постоји више потрошача који желе да узимају из бафера. Аналогно је за 1 произвођач и N потрошача.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== {{категорија|2. задатак|Монитори}} ==&lt;br /&gt;
{{делимично решено}}&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Аутомобили који долазе са севера и југа морају да пређу реку преко неког старог моста (&amp;lt;code&amp;gt;Old Bridge problem&amp;lt;/code&amp;gt;). На мосту постоји само једна возна трака, па сви аутомобили на мосту морају да се крећу у истом смеру. Због оптерећења моста које мост може да поднесе, број аутомобила који се налазе на мосту не сме да пређе K (K &amp;gt; 0). Написати монитор са &amp;lt;code&amp;gt;signal and continue&amp;lt;/code&amp;gt; дисциплином који решава дати проблем.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
const K = ...;&lt;br /&gt;
&lt;br /&gt;
monitor Bridge {&lt;br /&gt;
  int waitingS = 0, waitingN = 0;&lt;br /&gt;
  int cnt = 0;  // тренутан број аутића на мосту&lt;br /&gt;
  int dir = 0;  // 0 - нико не чека и нико није на мосту, 1 - тренутно прелазе&lt;br /&gt;
                // кола са севера, 2 - са југа&lt;br /&gt;
  cond goN, goS;&lt;br /&gt;
&lt;br /&gt;
  void EnterNorth() {&lt;br /&gt;
    waitingN++;&lt;br /&gt;
    // Чекај ако прелазе кола са југа или ако је на мосту већ К аутића&lt;br /&gt;
    while (dir == 2 || cnt == K) {&lt;br /&gt;
      wait(goN);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    waitingN--;&lt;br /&gt;
    dir = 1;&lt;br /&gt;
    cnt++;&lt;br /&gt;
&lt;br /&gt;
    // Ако има још места на мосту и има аутића који чекају - сигнализирај&lt;br /&gt;
    if (cnt &amp;lt; K &amp;amp;&amp;amp; goN.queue) {&lt;br /&gt;
      signal(goN);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void ExitNorth() {&lt;br /&gt;
    cnt--;&lt;br /&gt;
    if (cnt == 0) {        // мост је слободан&lt;br /&gt;
      if (waitingS &amp;gt; 0) {  // прво проверава супротан смер и препушта мост њима ако неко чека&lt;br /&gt;
        dir = 2;&lt;br /&gt;
        signal(goS);&lt;br /&gt;
      } else if (waitingN &amp;gt; 0) {&lt;br /&gt;
        dir = 1;&lt;br /&gt;
        signal(goN);&lt;br /&gt;
      } else {&lt;br /&gt;
        dir = 0;&lt;br /&gt;
      }&lt;br /&gt;
    } else {  // Мост није празан, ако неко чека на северу пропуштамо&lt;br /&gt;
      if (waitingN &amp;gt; 0) {&lt;br /&gt;
        signal(goN);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void EnterSouth() {&lt;br /&gt;
    waitingS++;&lt;br /&gt;
    while (dir == 1 || cnt == K) {&lt;br /&gt;
      wait(goS);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    waitingS--;&lt;br /&gt;
    dir = 2;&lt;br /&gt;
    cnt++;&lt;br /&gt;
&lt;br /&gt;
    if (cnt &amp;lt; K &amp;amp;&amp;amp; goS.queue) {&lt;br /&gt;
      signal(goS);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void ExitSouth() {&lt;br /&gt;
    cnt--;&lt;br /&gt;
    if (cnt == 0) {&lt;br /&gt;
      if (waitingN &amp;gt; 0) {&lt;br /&gt;
        dir = 1;&lt;br /&gt;
        signal(goN);&lt;br /&gt;
      } else if (waitingS &amp;gt; 0) {&lt;br /&gt;
        dir = 2;&lt;br /&gt;
        signal(goS);&lt;br /&gt;
      } else {&lt;br /&gt;
        dir = 0;&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      if (waitingS &amp;gt; 0) {&lt;br /&gt;
        signal(goS);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== {{категорија|3. задатак|CSP}} ==&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Решити проблем читалаца и писаца користећи &#039;&#039;CSP&#039;&#039;. Решење треба да обезбеди да када стигне захтев од писца за тражење дозволе за започињање писања не треба прихватати захтеве за започињање било од читалаца било од писаца док тај писац не заврши са писањем.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
[reader(i:1..N)::READER || writer(i:1..M)::WRITER || conductor::CONDUCTOR]&lt;br /&gt;
&lt;br /&gt;
READER :: *[&lt;br /&gt;
    conductor!request&lt;br /&gt;
    conductor!pass&lt;br /&gt;
    // reading&lt;br /&gt;
    conductor!done&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
WRITER :: *[&lt;br /&gt;
    conductor!request&lt;br /&gt;
    conductor!pass&lt;br /&gt;
    // writing&lt;br /&gt;
    conductor!done&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
CONDUCTOR :: [&lt;br /&gt;
    read_count: integer = 0&lt;br /&gt;
    write_count: integer = 0&lt;br /&gt;
    queue: (0..C) integer&lt;br /&gt;
    who: (0..C) char&lt;br /&gt;
    head: integer = 0&lt;br /&gt;
    tail: integer = 0&lt;br /&gt;
    *[&lt;br /&gt;
        head == tail, write_count == 0, (i:1..N) reader(i)?request -&amp;gt;&lt;br /&gt;
            reader(i)!pass&lt;br /&gt;
            read_count++&lt;br /&gt;
        □&lt;br /&gt;
        head == tail, write_count == 0, read_count == 0, (i:1..M) writer(i)?request -&amp;gt;&lt;br /&gt;
            writer(i)!pass&lt;br /&gt;
            write_count++&lt;br /&gt;
        □&lt;br /&gt;
        (head + 1) % N != tail, write_count + read_count != 0, (i:1..N) reader(i)?request -&amp;gt;&lt;br /&gt;
            queue(head) = i&lt;br /&gt;
            who(head) = &#039;r&#039;&lt;br /&gt;
            head = (head + 1) % N&lt;br /&gt;
        □&lt;br /&gt;
        (head + 1) % N != tail, write_count + read_count != 0, (i:1..M) writer(i)?request -&amp;gt;&lt;br /&gt;
            queue(head) = i&lt;br /&gt;
            who(head) = &#039;w&#039;&lt;br /&gt;
            head = (head + 1) % N&lt;br /&gt;
        □&lt;br /&gt;
        read_count == 1, (i:1..N) reader(i)?done -&amp;gt;&lt;br /&gt;
            read_count--&lt;br /&gt;
            *[&lt;br /&gt;
                head != tail, write_count == 0, who[tail] == &#039;r&#039; -&amp;gt;&lt;br /&gt;
                    reader(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    read_count++&lt;br /&gt;
                □&lt;br /&gt;
                head != tail, write_count == 0, read_count == 0, who[tail] == &#039;w&#039; -&amp;gt;&lt;br /&gt;
                    writer(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    write_count++&lt;br /&gt;
            ]&lt;br /&gt;
        □&lt;br /&gt;
        read_count != 1, (i:1..N) reader(i)?done -&amp;gt;&lt;br /&gt;
            read_count--&lt;br /&gt;
        □&lt;br /&gt;
        (i:1..M) writer(i)?done -&amp;gt;&lt;br /&gt;
            write_count--&lt;br /&gt;
            *[&lt;br /&gt;
                head != tail, write_count == 0, who[tail] == &#039;r&#039; -&amp;gt;&lt;br /&gt;
                    reader(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    read_count++&lt;br /&gt;
                □&lt;br /&gt;
                head != tail, write_count == 0, read_count == 0, who[tail] == &#039;w&#039; -&amp;gt;&lt;br /&gt;
                    writer(queue(tail))!pass&lt;br /&gt;
                    tail = (tail + 1) % N&lt;br /&gt;
                    write_count++&lt;br /&gt;
            ]&lt;br /&gt;
    ]&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== {{категорија|4. задатак|C-Linda}} ==&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Трајект за превоз возила превози возила са обале на обалу. Трајект поседује M трака од којих свака има N позиција које су линеарно постављене једна иза друге. Возило заузима једну позицију. Возило приликом доласка стаје у ред за случајно изабрану траку и чека на укрцавање. Нема могућности за престројавањем. Возила улазе у своју траку једно по једно по редоследу у којем чекају у траци, док на трајекту има места. Када је пун, трајект започиње превоз возила на другу обалу. На другој обали возила се искрцавају из своје траке у редоследу супротном од редоследа у којем су се укрцала у своју траку. Када се сва возила искрцају, празан трајект се враћа на почетну обалу. Користећи &#039;&#039;C-Linda&#039;&#039; написати програм који решава овај проблем.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категорија:КДП]]&lt;br /&gt;
[[Категорија:Рокови]]&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%9A2_2019&amp;diff=8384</id>
		<title>КДП/К2 2019</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%9A2_2019&amp;diff=8384"/>
		<updated>2026-06-08T15:54:07Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: /* Решење */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}&lt;br /&gt;
&#039;&#039;&#039;Други колоквијум 2019. године&#039;&#039;&#039; одржан је 23. априла. Поставка се може наћи са [https://rti.etf.bg.ac.rs/rti/ir3kdp/rokovi/kdp19.zip странице предмета] (зипована).&lt;br /&gt;
&lt;br /&gt;
== {{категорија|1. задатак|Монитори}} ==&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
Проблем филозофа који ручавају (&#039;&#039;Dining Philosophers Problem&#039;&#039;). Решити проблем филозофа који ручавају користећи мониторе са &#039;&#039;signal and wait&#039;&#039; дисциплином. Филозофи који су раније изразили жељу за храном треба раније да буду опслужени.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
class DiningPhilosophers {&lt;br /&gt;
    public static final int N = 10;&lt;br /&gt;
    boolean forks[] = new boolean[N];&lt;br /&gt;
    Condition queue = new Condition();&lt;br /&gt;
    int ticket = 1;&lt;br /&gt;
    private int left(int id) {&lt;br /&gt;
        return id;&lt;br /&gt;
    }&lt;br /&gt;
    private int right(int id) {&lt;br /&gt;
        return (id + 1) % id;&lt;br /&gt;
    }&lt;br /&gt;
    public synchronized void acquireForks(int id) {&lt;br /&gt;
        if (queue.queue() || forks[left(id)] || forks[right(id)]) {&lt;br /&gt;
            queue.wait((ticket++) * N + id);&lt;br /&gt;
        }&lt;br /&gt;
        forks[left(id)] = true;&lt;br /&gt;
        forks[right(id)] = true;&lt;br /&gt;
        signal();&lt;br /&gt;
    }&lt;br /&gt;
    public synchronized void releaseForks(int id) {&lt;br /&gt;
        forks[left(id)] = false;&lt;br /&gt;
        forks[right(id)] = false;&lt;br /&gt;
        signal();&lt;br /&gt;
    }&lt;br /&gt;
    private void signal() {&lt;br /&gt;
        if (queue.empty()) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        int id = queue.minrank() % N;&lt;br /&gt;
        if (!forks[left(id)] &amp;amp;&amp;amp; !forks[right(id)]) {&lt;br /&gt;
            queue.signal();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== {{категорија|2. задатак|Региони}} ==&lt;br /&gt;
=== Поставка ===&lt;br /&gt;
У берберници раде два берберина, Аца и Браца, постоји 10 столица за чекање и још петоро муштерија може да стоји и чека. Муштерије које долазе се изјашњавају да ли чекају код Аце или Браце или им је свеједно ко ће да их услужи. Ако муштерија види да нема места у берберници и не може бити услужена, одлази. Када је берберин слободан, муштерија која је најдуже чекала ће прва бити услужена (осим ако чека на другог берберина и тада тражимо следећу муштерију у низу). Када се ослободи столица за чекање, муштерија која је најдуже стајала треба да седне. Уколико је неки од берберина беспослен, он спава, и прва муштерија која код њега дође на ред треба да га пробуди и буде услужена. Користећи условне критичне регионе решити овај проблем.&lt;br /&gt;
&lt;br /&gt;
=== Решење ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;common.h&amp;quot;&lt;br /&gt;
#include &amp;lt;map&amp;gt;&lt;br /&gt;
#include &amp;lt;queue&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
struct BarberShop {&lt;br /&gt;
    // Додељивање идентификатора муштеријама по реду доласка&lt;br /&gt;
    int ticket = 1;&lt;br /&gt;
    // Идентификатор особе која седи у седишту, или 0 уколико нико не седи&lt;br /&gt;
    int seat[2] = {0};&lt;br /&gt;
    // Да ли је берберин завршио са шишањем и чека особу да плати&lt;br /&gt;
    bool finished[2] = {false};&lt;br /&gt;
    // std::map је подразумевано сортиран&lt;br /&gt;
    map&amp;lt;int, int&amp;gt; waitingQueue;&lt;br /&gt;
    // Редови чекања за муштерије код Аце, Браце и оне којима је свеједно&lt;br /&gt;
    queue&amp;lt;int&amp;gt; barberQueue[3];&lt;br /&gt;
};&lt;br /&gt;
BarberShop shop;&lt;br /&gt;
&lt;br /&gt;
const int ACA_ID = 0;&lt;br /&gt;
const int BRACA_ID = 1;&lt;br /&gt;
const int ANY_ID = 2;&lt;br /&gt;
&lt;br /&gt;
void barber(int id) {&lt;br /&gt;
    while (true) {&lt;br /&gt;
        region (shop) {&lt;br /&gt;
            // Спавамо док чекамо да прва особа која дође седне на столицу&lt;br /&gt;
            await (shop.seat[id] != 0);&lt;br /&gt;
        }&lt;br /&gt;
        // Шишање&lt;br /&gt;
        region (shop) {&lt;br /&gt;
            // Завршено шишање, чекамо на плаћање&lt;br /&gt;
            shop.finished[id] = true;&lt;br /&gt;
            await (!shop.finished[id]);&lt;br /&gt;
            // Узимамо следећу муштерију&lt;br /&gt;
            if (!shop.barberQueue[id].empty()) {&lt;br /&gt;
                shop.seat[id] = shop.barberQueue[id].front();&lt;br /&gt;
                shop.barberQueue[id].pop();&lt;br /&gt;
            } else if (!shop.barberQueue[ANY_ID].empty()) {&lt;br /&gt;
                shop.seat[id] = shop.barberQueue[ANY_ID].front();&lt;br /&gt;
                shop.barberQueue[ANY_ID].pop();&lt;br /&gt;
            } else {&lt;br /&gt;
                shop.seat[id] = 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Да ли је седиште за шишање код одређеног берберина тренутно резервисано за неку особу&lt;br /&gt;
int barberEquals(int barberId, int value) {&lt;br /&gt;
    if (barberId == ACA_ID &amp;amp;&amp;amp; shop.seat[ACA_ID] == value) {&lt;br /&gt;
        return ACA_ID;&lt;br /&gt;
    }&lt;br /&gt;
    if (barberId == BRACA_ID &amp;amp;&amp;amp; shop.seat[BRACA_ID] == value) {&lt;br /&gt;
        return BRACA_ID;&lt;br /&gt;
    }&lt;br /&gt;
    if (barberId == ANY_ID) {&lt;br /&gt;
        if (shop.seat[ACA_ID] == value) {&lt;br /&gt;
            return ACA_ID;&lt;br /&gt;
        }&lt;br /&gt;
        if (shop.seat[BRACA_ID] == value) {&lt;br /&gt;
            return BRACA_ID;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return -1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int barberFree(int barberId) {&lt;br /&gt;
    return barberEquals(barberId, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void client(int barberId) {&lt;br /&gt;
    region (shop) {&lt;br /&gt;
        if (shop.waitingQueue.size() == 15 &amp;amp;&amp;amp; barberFree(barberId) == -1) {&lt;br /&gt;
            // Особа не може бити услужена&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        int myTicket = shop.ticket++;&lt;br /&gt;
        if (barberFree(barberId) != -1) {&lt;br /&gt;
            // Без чекања седамо на столицу за шишање&lt;br /&gt;
            shop.seat[barberFree(barberId)] = myTicket;&lt;br /&gt;
        } else {&lt;br /&gt;
            shop.barberQueue[barberId].push(myTicket);&lt;br /&gt;
            // Овиме повећавамо shop.waitingQueue.size()&lt;br /&gt;
            shop.waitingQueue[myTicket] = shop.waitingQueue.size();&lt;br /&gt;
            // Чекамо на столицу за чекање или шишање&lt;br /&gt;
            await (shop.waitingQueue[myTicket] &amp;lt; 10 || barberEquals(barberId, myTicket) != -1);&lt;br /&gt;
            if (barberEquals(barberId, myTicket) == -1) {&lt;br /&gt;
                // Седамо на столицу за чекање&lt;br /&gt;
                await (barberEquals(barberId, myTicket) != -1);&lt;br /&gt;
            }&lt;br /&gt;
            // Устали смо са столице и смањујемо shop.waitingQueue.size&lt;br /&gt;
            shop.waitingQueue.erase(myTicket);&lt;br /&gt;
            int i = 0;&lt;br /&gt;
            for (auto&amp;amp; it : shop.waitingQueue) {&lt;br /&gt;
                shop.waitingQueue[it.first] = i++;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        int barber = barberEquals(barberId, myTicket);&lt;br /&gt;
        // Чекање током шишања&lt;br /&gt;
        await (shop.finished[barber]);&lt;br /&gt;
        // Плаћање&lt;br /&gt;
        shop.finished[barber] = false;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Категорија:КДП]]&lt;br /&gt;
[[Категорија:Рокови]]&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%9B%D0%B0%D0%B1_1_2024&amp;diff=8382</id>
		<title>КДП/Лаб 1 2024</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%9B%D0%B0%D0%B1_1_2024&amp;diff=8382"/>
		<updated>2026-06-04T11:30:13Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: /* Philosopher.java */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Прва лабораторијска вежба 2024. године&#039;&#039;&#039; одржана је 29. i 30. априла и носила је 10 бодова (3 бода Moodle 7 бодова задатак). Укупно је било 4 групе. &lt;br /&gt;
&lt;br /&gt;
== Улазни тест Група 1 и 2 ==&lt;br /&gt;
&lt;br /&gt;
=== 1. задатак ===&lt;br /&gt;
Уколико нит А позове a(), а нит Б позове b(), шта ће се десити са нити Б?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class A {&lt;br /&gt;
	public synchronized void a() {&lt;br /&gt;
		//neki kod ...&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public synchronized void b() {&lt;br /&gt;
		//neki kod..&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	A obj = new A();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Одговор: &amp;lt;span class=&amp;quot;spoiler&amp;quot; data-solution=&amp;quot;text&amp;quot;&amp;gt;Зауставиће се док се не изврши a()&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од следећег су валидни начини да се иницијализује нит?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
	    public void run(){ /*neki kod*/ }&lt;br /&gt;
	};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
		public void run(){ /*neki kod*/}&lt;br /&gt;
	};&lt;br /&gt;
Thread t = new Thread(r);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;public class Nit extends Thread {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
}&lt;br /&gt;
Nit t = new Nit();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread() {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. задатак ===&lt;br /&gt;
&lt;br /&gt;
Прва нит извршава &amp;lt;code&amp;gt;readMethod()&amp;lt;/code&amp;gt; и закључала је &amp;lt;code&amp;gt;readLock&amp;lt;/code&amp;gt;. Друга нит је позвала &amp;lt;code&amp;gt;writeMethod()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class LockExample {&lt;br /&gt;
    private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();&lt;br /&gt;
&lt;br /&gt;
    public void readMethod() {&lt;br /&gt;
        rwLock.readLock().lock();&lt;br /&gt;
        try {&lt;br /&gt;
            // Neki kod...&lt;br /&gt;
        } finally {&lt;br /&gt;
            rwLock.readLock().unlock();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void writeMethod() {&lt;br /&gt;
        if (!rwLock.isWriteLocked()) {&lt;br /&gt;
            rwLock.writeLock().lock();&lt;br /&gt;
            try {&lt;br /&gt;
                // Neki kod..&lt;br /&gt;
            } finally {&lt;br /&gt;
                rwLock.writeLock().unlock();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чему служи параметар у конструктору &amp;lt;code&amp;gt;ReentrantReadWriteLock&amp;lt;/code&amp;gt;?&lt;br /&gt;
Одговор: &amp;lt;span class=&amp;quot;spoiler&amp;quot; data-solution=&amp;quot;text&amp;quot;&amp;gt;FIFO Fairness&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шта се дешава са другом нити?&lt;br /&gt;
Одговор: &amp;lt;span class=&amp;quot;spoiler&amp;quot; data-solution=&amp;quot;text&amp;quot;&amp;gt;Блокира се на &amp;lt;code&amp;gt;writeLock&amp;lt;/code&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Улазни тест Групe 3 ==&lt;br /&gt;
&lt;br /&gt;
=== 1. задатак ===&lt;br /&gt;
Када нит T увек трајно престаје да се извршава?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;single&amp;quot;&amp;gt;&lt;br /&gt;
# Када нит позове wait над неким објектом.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Када се заврши њена run метода.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Када позове своју interrupt методу.&lt;br /&gt;
# Ниједан од понуђених одговора.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од наведених исказа су тачни?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;&amp;lt;code&amp;gt;ArrayBlockingQueue&amp;lt;/code&amp;gt; je pogodan za rešavanje ProducerConsumer problema.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;add(E e) i remove()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt; Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeLast()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;transfer(E e) i take()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;TransferQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeFirst()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. задатак ===&lt;br /&gt;
&lt;br /&gt;
Уколико нит threadA тренутно извршава методу обј.а(), а потом нит threadB позива методу обј.б(), који од понуђених одговора су тачни, уколико је дат следећи део кода?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class A {&lt;br /&gt;
  private ReentrantReadWriteLock rw = new ReentrantReadWriteLock(true);&lt;br /&gt;
&lt;br /&gt;
  public void a() {&lt;br /&gt;
    try {&lt;br /&gt;
      rw.readLock().lock();&lt;br /&gt;
      // kritična sekcija A...  // &amp;lt;- threadA&lt;br /&gt;
    } finally {&lt;br /&gt;
      rw.readLock().unlock();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public void b() {&lt;br /&gt;
    try {&lt;br /&gt;
      if (rw.getReadLockCount()==0) {&lt;br /&gt;
        rw.writeLock().lock();&lt;br /&gt;
      }&lt;br /&gt;
      // kritična sekcija B...&lt;br /&gt;
    } finally {&lt;br /&gt;
      rw.writeLock().unlock();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
A obj = new A();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt; Десиће се грешка приликом извршавања.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Аргумент конструктора ReentrantReadWriteLock означава да могу две нити истовремено да позивају закључавање.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Нити А и Б могу истовремено да извршавају критичне секције у методама a() и b() (респективно).&amp;lt;/span&amp;gt;&lt;br /&gt;
# Нит Б ће бити блокирана док нит А не заврши позив методе a().&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Аргумент конструктора ReentrantReadWriteLock означава да ли ће се буђење нити обављати по FIFO принципу.&amp;lt;/span&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Нит Б неће извршити закључавање, јер услов if-a није испуњен.&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Улазни тест Групe 4 ==&lt;br /&gt;
&lt;br /&gt;
=== 1. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од следећег су валидни начини да се иницијализује нит?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
	    public void run(){ /*neki kod*/ }&lt;br /&gt;
	};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
		public void run(){ /*neki kod*/}&lt;br /&gt;
	};&lt;br /&gt;
Thread t = new Thread(r);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;public class Nit extends Thread {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
}&lt;br /&gt;
Nit t = new Nit();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread() {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од наведених исказа су тачни?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;&amp;lt;code&amp;gt;ArrayBlockingQueue&amp;lt;/code&amp;gt; je pogodan za rešavanje ProducerConsumer problema.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;add(E e) i remove()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt; Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeLast()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;transfer(E e) i take()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;TransferQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeFirst()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. задатак ===&lt;br /&gt;
&lt;br /&gt;
Како правилно осигурати међусобно искључивање критичне секције?&lt;br /&gt;
&lt;br /&gt;
{{delimično rešeno}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Поставка Свих Група==&lt;br /&gt;
&lt;br /&gt;
У зависности од групе било је потребно решити један од следећих проблема:&lt;br /&gt;
&lt;br /&gt;
1. Решити &amp;lt;code&amp;gt;Atomic Broadcast&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;AtomicInteger&amp;lt;/code&amp;gt; и опционо &amp;lt;code&amp;gt;Semaphore&amp;lt;/code&amp;gt; . Бафер садржи B елемената. Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
2. Решити &amp;lt;code&amp;gt;H2O&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;CyclicBarrier&amp;lt;/code&amp;gt;. Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
3. Решити &amp;lt;code&amp;gt;Dining Philosophers&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;AtomicInteger&amp;lt;/code&amp;gt; и регионе. филозофи који су раније изразили жељу за храном треба раније да буду опслужени . Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
4. Решити &amp;lt;code&amp;gt;Child Care&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;ConcurrentLinkedQueue&amp;lt;/code&amp;gt; и друге произвољне синхронизационе директиве. Родитељ доводи једно или више деце у обданиште и чека све док се не појави место, како би оставио сву децу одједном и отишао. Родитељ може и да одведе једно или више деце, такође одједном. Мора се поштовати редослед доласка родитеља који остављају децу и васпитачица које одлазе са посла. Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
== Решење за Atomic Broadcast ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G1;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
&lt;br /&gt;
	private static final int consumersCount=3;&lt;br /&gt;
	private static final int b=5;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
		AtomicInteger[][] reads = new AtomicInteger[b][consumersCount];&lt;br /&gt;
&lt;br /&gt;
		Semaphore mutex = new Semaphore(1);&lt;br /&gt;
&lt;br /&gt;
		AtomicInteger[] buffer = new AtomicInteger[b];&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; buffer.length; i++)&lt;br /&gt;
			buffer[i] = new AtomicInteger(0);&lt;br /&gt;
&lt;br /&gt;
		Consumer[] consumers = new Consumer[consumersCount];&lt;br /&gt;
&lt;br /&gt;
		Producer p = new Producer(consumersCount, buffer, reads,b,mutex);&lt;br /&gt;
		p.start();&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; b; i++)&lt;br /&gt;
			for(int j=0;j&amp;lt;consumersCount;j++)&lt;br /&gt;
				reads[i][j] = new AtomicInteger(0);&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; consumersCount; i++) {&lt;br /&gt;
			consumers[i] = new Consumer(buffer, reads,b,mutex,i);&lt;br /&gt;
			consumers[i].start();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Producer.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G1;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Producer extends Thread {&lt;br /&gt;
&lt;br /&gt;
	private final int consumers;&lt;br /&gt;
	private AtomicInteger[] buffer;&lt;br /&gt;
	private AtomicInteger[][] reads;&lt;br /&gt;
	private Semaphore mutex;&lt;br /&gt;
	private int b;&lt;br /&gt;
&lt;br /&gt;
	public Producer(int consumers, AtomicInteger[] buffer, AtomicInteger[][] reads, int bb, Semaphore mutex) {&lt;br /&gt;
		this.consumers = consumers;&lt;br /&gt;
		this.buffer = buffer;&lt;br /&gt;
		this.reads = reads;&lt;br /&gt;
		b=bb;&lt;br /&gt;
		this.mutex = mutex;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		for (int i = 0; i &amp;lt;b; i++) {&lt;br /&gt;
			for (int j = 0; j &amp;lt; consumers; j++)&lt;br /&gt;
				while(reads[i][j].get() == 1)&lt;br /&gt;
					Thread.onSpinWait();&lt;br /&gt;
&lt;br /&gt;
			int rand = (int)(Math.random() * 10);&lt;br /&gt;
			System.out.println(&amp;quot;Producer produced element: &amp;quot; + rand );&lt;br /&gt;
			mutex.acquireUninterruptibly();&lt;br /&gt;
			buffer[i].set(rand);&lt;br /&gt;
			mutex.release();&lt;br /&gt;
&lt;br /&gt;
			mutex.acquireUninterruptibly();&lt;br /&gt;
			for (int j2 = 0; j2 &amp;lt; consumers; j2++)&lt;br /&gt;
				reads[i][j2].set(0);&lt;br /&gt;
&lt;br /&gt;
			mutex.release();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Consumer.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G1;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Consumer extends Thread {&lt;br /&gt;
&lt;br /&gt;
	private int id;&lt;br /&gt;
	private AtomicInteger[][] reads;&lt;br /&gt;
	private AtomicInteger[] buffer;&lt;br /&gt;
	private Semaphore mutex;&lt;br /&gt;
	private int b;&lt;br /&gt;
&lt;br /&gt;
	public Consumer(AtomicInteger[] buff, AtomicInteger[][] r, int bb,Semaphore mutex, int i) {&lt;br /&gt;
		buffer = buff;&lt;br /&gt;
		reads=r;&lt;br /&gt;
		id=i;&lt;br /&gt;
		this.mutex = mutex;&lt;br /&gt;
		b=bb;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		for (int i = 0; i &amp;lt; b; i++) {&lt;br /&gt;
			while(reads[i][id].get() == 1)&lt;br /&gt;
				Thread.onSpinWait();&lt;br /&gt;
			mutex.acquireUninterruptibly();&lt;br /&gt;
			int elem = buffer[i].get();&lt;br /&gt;
			System.out.println(&amp;quot;Consumer &amp;quot;+id+&amp;quot; consumed element &amp;quot;+elem +&amp;quot;from place &amp;quot;+i);&lt;br /&gt;
			reads[i][id].set(1);&lt;br /&gt;
			mutex.release();&lt;br /&gt;
&lt;br /&gt;
			try {&lt;br /&gt;
				sleep((int)(Math.random()*2000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				throw new RuntimeException(e);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Решење за H2O ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.CyclicBarrier;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int cnt = 10;&lt;br /&gt;
		&lt;br /&gt;
		Barrier barrier = new Barrier(new CyclicBarrier(3));&lt;br /&gt;
		&lt;br /&gt;
		Hydrogen[] h = new Hydrogen[cnt*2];&lt;br /&gt;
		Oxygen[] o = new Oxygen[cnt];&lt;br /&gt;
		&lt;br /&gt;
		for(int i = 0; i &amp;lt; cnt; i++) {&lt;br /&gt;
			o[i] = new Oxygen(barrier);&lt;br /&gt;
			h[2*i] = new Hydrogen(barrier);	&lt;br /&gt;
			h[2*i + 1] = new Hydrogen(barrier);	&lt;br /&gt;
			&lt;br /&gt;
			o[i].start();&lt;br /&gt;
			h[2*i].start();&lt;br /&gt;
			h[2*i+1].start();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== &amp;lt;code&amp;gt;Oxygen.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.BrokenBarrierException;&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
&lt;br /&gt;
public class Oxygen extends Thread {&lt;br /&gt;
	&lt;br /&gt;
	Barrier barrier;&lt;br /&gt;
	&lt;br /&gt;
	Oxygen(Barrier b){&lt;br /&gt;
		barrier = b;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep((int)(Math.random() * 4000));&lt;br /&gt;
			} catch (InterruptedException e) {}&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			barrier.oxygen.acquireUninterruptibly();&lt;br /&gt;
&lt;br /&gt;
			barrier.oCount++;&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
				System.out.println(&amp;quot;Kiseonik pristigao na barijeru&amp;quot;);&lt;br /&gt;
				&lt;br /&gt;
				if(barrier.barrier.await() == 0) {&lt;br /&gt;
					System.out.println(&amp;quot;\nFORMIRANJE VODE!\n&amp;quot;);&lt;br /&gt;
					&lt;br /&gt;
					barrier.hCount = 0;&lt;br /&gt;
					barrier.oCount = 1;&lt;br /&gt;
					&lt;br /&gt;
					barrier.hydrogen.release(2);&lt;br /&gt;
					barrier.oxygen.release(1);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
			} catch (InterruptedException | BrokenBarrierException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Hydrogen.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.BrokenBarrierException;&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
&lt;br /&gt;
public class Hydrogen extends Thread {&lt;br /&gt;
	&lt;br /&gt;
	Barrier barrier;&lt;br /&gt;
	&lt;br /&gt;
	Hydrogen(Barrier b){&lt;br /&gt;
		barrier = b;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep((int)(Math.random() * 4000));&lt;br /&gt;
			} catch (InterruptedException e) {}&lt;br /&gt;
			&lt;br /&gt;
			barrier.hydrogen.acquireUninterruptibly();&lt;br /&gt;
&lt;br /&gt;
			barrier.hCount++;&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
				System.out.println(&amp;quot;Vodonik pristigao na barijeru&amp;quot;);&lt;br /&gt;
				&lt;br /&gt;
				if(barrier.barrier.await() == 0) {&lt;br /&gt;
					System.out.println(&amp;quot;\nFORMIRANJE VODE!\n&amp;quot;);&lt;br /&gt;
					barrier.hCount = 0;&lt;br /&gt;
					barrier.oCount = 1;&lt;br /&gt;
					&lt;br /&gt;
					barrier.hydrogen.release(2);&lt;br /&gt;
					barrier.oxygen.release(1);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
			} catch (InterruptedException | BrokenBarrierException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Barrier.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.CyclicBarrier;&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
&lt;br /&gt;
public class Barrier {&lt;br /&gt;
	CyclicBarrier barrier;&lt;br /&gt;
	Semaphore hydrogen, oxygen;&lt;br /&gt;
	int hCount, oCount;&lt;br /&gt;
	&lt;br /&gt;
	Barrier(CyclicBarrier cb){&lt;br /&gt;
		barrier = cb;&lt;br /&gt;
		hCount = 0;&lt;br /&gt;
		oCount = 0;&lt;br /&gt;
		hydrogen = new Semaphore(2);&lt;br /&gt;
		oxygen = new Semaphore(1);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Решење за Dining Philosophers ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G3;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
&lt;br /&gt;
	public static final int N = 5;&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
		Philosopher[] philosophers = new Philosopher[N];&lt;br /&gt;
		AtomicInteger[] forks = new AtomicInteger[N];&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; forks.length; i++)&lt;br /&gt;
			forks[i] = new AtomicInteger(1);&lt;br /&gt;
&lt;br /&gt;
		Table table = new Table();&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; N; i++) {&lt;br /&gt;
			philosophers[i] = new Philosopher(forks, i, N, table);&lt;br /&gt;
			philosophers[i].start();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== &amp;lt;code&amp;gt;Table.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G3;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Table {&lt;br /&gt;
&lt;br /&gt;
	AtomicInteger ticket;&lt;br /&gt;
	int next;&lt;br /&gt;
&lt;br /&gt;
	public Table() {&lt;br /&gt;
		ticket = new AtomicInteger(0);&lt;br /&gt;
		next = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Philosopher.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G3;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Philosopher extends Thread {&lt;br /&gt;
&lt;br /&gt;
	AtomicInteger[] forks;&lt;br /&gt;
	int id,left,right,N,myTicket;&lt;br /&gt;
	Table t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public Philosopher(AtomicInteger[] forks, int id, int n,Table table) {&lt;br /&gt;
		this.forks = forks;&lt;br /&gt;
		this.id = id;&lt;br /&gt;
		N = n;&lt;br /&gt;
		left = id;&lt;br /&gt;
		right = (id+1)%n;&lt;br /&gt;
		t = table;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			think();&lt;br /&gt;
            run();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public void think() {&lt;br /&gt;
		System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; thinking&amp;quot;);&lt;br /&gt;
		try {&lt;br /&gt;
			sleep((int)(Math.random() * 3000));&lt;br /&gt;
		} catch (InterruptedException e) {&lt;br /&gt;
			// TODO Auto-generated catch block&lt;br /&gt;
			e.printStackTrace();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public void eat() {&lt;br /&gt;
		myTicket = t.ticket.getAndIncrement();&lt;br /&gt;
		synchronized (forks) {&lt;br /&gt;
&lt;br /&gt;
			System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; wants to eat&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
			while(forks[left].intValue() == 0 || forks[right].intValue() == 0 || myTicket != t.next)&lt;br /&gt;
				try {&lt;br /&gt;
					forks.wait();&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					// TODO Auto-generated catch block&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
			System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; started eating&amp;quot;);&lt;br /&gt;
			forks[left].set(0);&lt;br /&gt;
			forks[right].set(0);&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		try {&lt;br /&gt;
			sleep((int)(Math.random() * 2000));&lt;br /&gt;
		} catch (InterruptedException e) {&lt;br /&gt;
			// TODO Auto-generated catch block&lt;br /&gt;
			e.printStackTrace();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		synchronized (forks) {&lt;br /&gt;
&lt;br /&gt;
			System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; finished eating&amp;quot;);&lt;br /&gt;
			forks[left].set(1);&lt;br /&gt;
			forks[right].set(1);&lt;br /&gt;
			t.next++;&lt;br /&gt;
			forks.notifyAll();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Решење за Child Care ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		Kindergarten k = new Kindergarten(12);&lt;br /&gt;
		k.startProgram(4, 3);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== &amp;lt;code&amp;gt;Kindergarten.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.ConcurrentLinkedQueue;&lt;br /&gt;
&lt;br /&gt;
public class Kindergarten {&lt;br /&gt;
	int childrenInside = 0;&lt;br /&gt;
	int teachersInside = 0;&lt;br /&gt;
	int capacity;&lt;br /&gt;
	public ConcurrentLinkedQueue&amp;lt;Integer&amp;gt; parentQueue;&lt;br /&gt;
	public ConcurrentLinkedQueue&amp;lt;Integer&amp;gt; teacherQueue;&lt;br /&gt;
	public Kindergarten(int capacity) { &lt;br /&gt;
		parentQueue = new ConcurrentLinkedQueue&amp;lt;Integer&amp;gt;();&lt;br /&gt;
		teacherQueue = new ConcurrentLinkedQueue&amp;lt;Integer&amp;gt;();&lt;br /&gt;
		this.capacity = capacity;&lt;br /&gt;
	}&lt;br /&gt;
	public static boolean ruleFollowed(int teachers, int children, int capacity ) {&lt;br /&gt;
		if(teachers == 0 || children &amp;gt; capacity) return false;&lt;br /&gt;
		return teachers &amp;gt;= Math.ceil(children / 3.0);&lt;br /&gt;
	}&lt;br /&gt;
	public void startProgram(int teachersUsed, int parentsUsed) {&lt;br /&gt;
		Teacher[] teachers = new Teacher[teachersUsed];&lt;br /&gt;
		Parent[] parents = new Parent[parentsUsed];&lt;br /&gt;
		for(int i = 0; i &amp;lt; teachersUsed; i++) {&lt;br /&gt;
			teachers[i] = new Teacher(i, this);&lt;br /&gt;
			teachers[i].start();&lt;br /&gt;
		}&lt;br /&gt;
		for(int i = 0; i &amp;lt; parentsUsed; i++) {&lt;br /&gt;
			parents[i] = new Parent(i, this);&lt;br /&gt;
			parents[i].start();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Teacher.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
import java.util.Random;&lt;br /&gt;
import java.util.concurrent.ConcurrentLinkedQueue;&lt;br /&gt;
&lt;br /&gt;
public class Teacher extends Thread {&lt;br /&gt;
	Kindergarten k;&lt;br /&gt;
	int id;&lt;br /&gt;
	&lt;br /&gt;
	public Teacher(int id, Kindergarten k) {&lt;br /&gt;
		this.k = k;&lt;br /&gt;
		this.id = id;&lt;br /&gt;
	}&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			synchronized(k) {&lt;br /&gt;
				k.teachersInside++;&lt;br /&gt;
				System.out.println(&amp;quot;Teacher &amp;quot; + id + &amp;quot; came to work.&amp;quot;);&lt;br /&gt;
				k.notifyAll();&lt;br /&gt;
			}&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			synchronized(k) {&lt;br /&gt;
				k.teacherQueue.add(id);&lt;br /&gt;
				System.out.println(&amp;quot;Teacher &amp;quot; + id + &amp;quot; wishes to leave work.&amp;quot;);&lt;br /&gt;
				while(!(k.teacherQueue.element() == id &amp;amp;&amp;amp; Kindergarten.ruleFollowed(k.teachersInside - 1, k.childrenInside, k.capacity))) {&lt;br /&gt;
					try {&lt;br /&gt;
						k.wait();&lt;br /&gt;
					} catch (InterruptedException e) {&lt;br /&gt;
						e.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				System.out.println(&amp;quot;Teacher &amp;quot; + id + &amp;quot; has left work.&amp;quot;);&lt;br /&gt;
				k.teachersInside--;&lt;br /&gt;
				k.teacherQueue.remove();&lt;br /&gt;
				k.notifyAll();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Parent.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
import java.util.Random;&lt;br /&gt;
import java.util.concurrent.ConcurrentLinkedQueue;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class Parent extends Thread {&lt;br /&gt;
	&lt;br /&gt;
	boolean interacted = false;&lt;br /&gt;
	Kindergarten k;&lt;br /&gt;
	int id;&lt;br /&gt;
	public Parent(int id, Kindergarten k) {&lt;br /&gt;
		this.k = k;&lt;br /&gt;
		this.id = id;&lt;br /&gt;
	}&lt;br /&gt;
	public void run() {&lt;br /&gt;
		&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			int childrenBrought = 1 + new Random().nextInt(4);&lt;br /&gt;
			System.out.println(&amp;quot;Parent &amp;quot; + id + &amp;quot; brought &amp;quot; + childrenBrought + &amp;quot; children.&amp;quot;);&lt;br /&gt;
			interacted = false;&lt;br /&gt;
&lt;br /&gt;
			synchronized(k) {&lt;br /&gt;
				k.parentQueue.add(id);&lt;br /&gt;
				while(!(k.parentQueue.peek() == id &amp;amp;&amp;amp; Kindergarten.ruleFollowed(k.teachersInside, k.childrenInside + childrenBrought, k.capacity))) {&lt;br /&gt;
					try {&lt;br /&gt;
						k.wait();&lt;br /&gt;
					} catch (InterruptedException e) {&lt;br /&gt;
						e.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				k.parentQueue.remove();&lt;br /&gt;
				k.childrenInside += childrenBrought;&lt;br /&gt;
				System.out.println(&amp;quot;Parent &amp;quot; + id + &amp;quot; left his &amp;quot; + childrenBrought + &amp;quot; children.&amp;quot;);&lt;br /&gt;
				k.notifyAll();&lt;br /&gt;
			}&lt;br /&gt;
			while(childrenBrought &amp;gt; 0) {&lt;br /&gt;
				try {&lt;br /&gt;
					Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				int childrenToPickUp = 1 + (1 + new Random().nextInt(4)) % childrenBrought;&lt;br /&gt;
				synchronized(k) {&lt;br /&gt;
					k.childrenInside -= childrenToPickUp;&lt;br /&gt;
					System.out.println(&amp;quot;Parent &amp;quot; + id + &amp;quot; took home his &amp;quot; + childrenToPickUp + &amp;quot;/&amp;quot; + childrenBrought + &amp;quot; children.&amp;quot;);&lt;br /&gt;
					k.notifyAll();&lt;br /&gt;
				}&lt;br /&gt;
				childrenBrought -= childrenToPickUp;&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категорија:КДП]]&lt;br /&gt;
[[Категорија:Лабораторијске вежбе]]&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Ralepop&amp;diff=8381</id>
		<title>Корисник:Ralepop</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Ralepop&amp;diff=8381"/>
		<updated>2026-06-03T21:06:16Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: Уклоњено преусмерење на Корисник:Elar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;unpaid-lilac-gizmo@duck.com&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%9B%D0%B0%D0%B1_1_2024&amp;diff=8380</id>
		<title>КДП/Лаб 1 2024</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%94%D0%9F/%D0%9B%D0%B0%D0%B1_1_2024&amp;diff=8380"/>
		<updated>2026-06-03T21:05:14Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: /* Решење за Atomic Broadcast */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{tocright}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Прва лабораторијска вежба 2024. године&#039;&#039;&#039; одржана је 29. i 30. априла и носила је 10 бодова (3 бода Moodle 7 бодова задатак). Укупно је било 4 групе. &lt;br /&gt;
&lt;br /&gt;
== Улазни тест Група 1 и 2 ==&lt;br /&gt;
&lt;br /&gt;
=== 1. задатак ===&lt;br /&gt;
Уколико нит А позове a(), а нит Б позове b(), шта ће се десити са нити Б?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class A {&lt;br /&gt;
	public synchronized void a() {&lt;br /&gt;
		//neki kod ...&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public synchronized void b() {&lt;br /&gt;
		//neki kod..&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	A obj = new A();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Одговор: &amp;lt;span class=&amp;quot;spoiler&amp;quot; data-solution=&amp;quot;text&amp;quot;&amp;gt;Зауставиће се док се не изврши a()&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од следећег су валидни начини да се иницијализује нит?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
	    public void run(){ /*neki kod*/ }&lt;br /&gt;
	};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
		public void run(){ /*neki kod*/}&lt;br /&gt;
	};&lt;br /&gt;
Thread t = new Thread(r);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;public class Nit extends Thread {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
}&lt;br /&gt;
Nit t = new Nit();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread() {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. задатак ===&lt;br /&gt;
&lt;br /&gt;
Прва нит извршава &amp;lt;code&amp;gt;readMethod()&amp;lt;/code&amp;gt; и закључала је &amp;lt;code&amp;gt;readLock&amp;lt;/code&amp;gt;. Друга нит је позвала &amp;lt;code&amp;gt;writeMethod()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class LockExample {&lt;br /&gt;
    private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();&lt;br /&gt;
&lt;br /&gt;
    public void readMethod() {&lt;br /&gt;
        rwLock.readLock().lock();&lt;br /&gt;
        try {&lt;br /&gt;
            // Neki kod...&lt;br /&gt;
        } finally {&lt;br /&gt;
            rwLock.readLock().unlock();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void writeMethod() {&lt;br /&gt;
        if (!rwLock.isWriteLocked()) {&lt;br /&gt;
            rwLock.writeLock().lock();&lt;br /&gt;
            try {&lt;br /&gt;
                // Neki kod..&lt;br /&gt;
            } finally {&lt;br /&gt;
                rwLock.writeLock().unlock();&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чему служи параметар у конструктору &amp;lt;code&amp;gt;ReentrantReadWriteLock&amp;lt;/code&amp;gt;?&lt;br /&gt;
Одговор: &amp;lt;span class=&amp;quot;spoiler&amp;quot; data-solution=&amp;quot;text&amp;quot;&amp;gt;FIFO Fairness&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Шта се дешава са другом нити?&lt;br /&gt;
Одговор: &amp;lt;span class=&amp;quot;spoiler&amp;quot; data-solution=&amp;quot;text&amp;quot;&amp;gt;Блокира се на &amp;lt;code&amp;gt;writeLock&amp;lt;/code&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Улазни тест Групe 3 ==&lt;br /&gt;
&lt;br /&gt;
=== 1. задатак ===&lt;br /&gt;
Када нит T увек трајно престаје да се извршава?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;single&amp;quot;&amp;gt;&lt;br /&gt;
# Када нит позове wait над неким објектом.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Када се заврши њена run метода.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Када позове своју interrupt методу.&lt;br /&gt;
# Ниједан од понуђених одговора.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од наведених исказа су тачни?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;&amp;lt;code&amp;gt;ArrayBlockingQueue&amp;lt;/code&amp;gt; je pogodan za rešavanje ProducerConsumer problema.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;add(E e) i remove()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt; Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeLast()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;transfer(E e) i take()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;TransferQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeFirst()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. задатак ===&lt;br /&gt;
&lt;br /&gt;
Уколико нит threadA тренутно извршава методу обј.а(), а потом нит threadB позива методу обј.б(), који од понуђених одговора су тачни, уколико је дат следећи део кода?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class A {&lt;br /&gt;
  private ReentrantReadWriteLock rw = new ReentrantReadWriteLock(true);&lt;br /&gt;
&lt;br /&gt;
  public void a() {&lt;br /&gt;
    try {&lt;br /&gt;
      rw.readLock().lock();&lt;br /&gt;
      // kritična sekcija A...  // &amp;lt;- threadA&lt;br /&gt;
    } finally {&lt;br /&gt;
      rw.readLock().unlock();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  public void b() {&lt;br /&gt;
    try {&lt;br /&gt;
      if (rw.getReadLockCount()==0) {&lt;br /&gt;
        rw.writeLock().lock();&lt;br /&gt;
      }&lt;br /&gt;
      // kritična sekcija B...&lt;br /&gt;
    } finally {&lt;br /&gt;
      rw.writeLock().unlock();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
A obj = new A();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt; Десиће се грешка приликом извршавања.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Аргумент конструктора ReentrantReadWriteLock означава да могу две нити истовремено да позивају закључавање.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Нити А и Б могу истовремено да извршавају критичне секције у методама a() и b() (респективно).&amp;lt;/span&amp;gt;&lt;br /&gt;
# Нит Б ће бити блокирана док нит А не заврши позив методе a().&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Аргумент конструктора ReentrantReadWriteLock означава да ли ће се буђење нити обављати по FIFO принципу.&amp;lt;/span&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;Нит Б неће извршити закључавање, јер услов if-a није испуњен.&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Улазни тест Групe 4 ==&lt;br /&gt;
&lt;br /&gt;
=== 1. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од следећег су валидни начини да се иницијализује нит?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
	    public void run(){ /*neki kod*/ }&lt;br /&gt;
	};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Runnable r = new Runnable() {&lt;br /&gt;
		public void run(){ /*neki kod*/}&lt;br /&gt;
	};&lt;br /&gt;
Thread t = new Thread(r);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;public class Nit extends Thread {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
}&lt;br /&gt;
Nit t = new Nit();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; class=&amp;quot;solution&amp;quot;&amp;gt;Thread t = new Thread() {&lt;br /&gt;
	public void run(){ /*neki kod*/ }&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. задатак ===&lt;br /&gt;
&lt;br /&gt;
Који од наведених исказа су тачни?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;abc-list&amp;quot; data-solution=&amp;quot;multiple&amp;quot;&amp;gt;&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt;&amp;lt;code&amp;gt;ArrayBlockingQueue&amp;lt;/code&amp;gt; je pogodan za rešavanje ProducerConsumer problema.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;add(E e) i remove()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# &amp;lt;span class=&amp;quot;solution&amp;quot;&amp;gt; Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeLast()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&amp;lt;/span&amp;gt;&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;transfer(E e) i take()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;TransferQueue&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
# Za implementaciju &amp;lt;code&amp;gt;ProducerConsumer&amp;lt;/code&amp;gt; problema, može se koristiti par metoda &amp;lt;code&amp;gt;putFirst(E e) i takeFirst()&amp;lt;/code&amp;gt; objekta tipa &amp;lt;code&amp;gt;BlockingDeque&amp;lt;/code&amp;gt;, bez dodatnih sinhronizacionih elemenata/direktiva.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3. задатак ===&lt;br /&gt;
&lt;br /&gt;
Како правилно осигурати међусобно искључивање критичне секције?&lt;br /&gt;
&lt;br /&gt;
{{delimično rešeno}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Поставка Свих Група==&lt;br /&gt;
&lt;br /&gt;
У зависности од групе било је потребно решити један од следећих проблема:&lt;br /&gt;
&lt;br /&gt;
1. Решити &amp;lt;code&amp;gt;Atomic Broadcast&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;AtomicInteger&amp;lt;/code&amp;gt; и опционо &amp;lt;code&amp;gt;Semaphore&amp;lt;/code&amp;gt; . Бафер садржи B елемената. Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
2. Решити &amp;lt;code&amp;gt;H2O&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;CyclicBarrier&amp;lt;/code&amp;gt;. Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
3. Решити &amp;lt;code&amp;gt;Dining Philosophers&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;AtomicInteger&amp;lt;/code&amp;gt; и регионе. филозофи који су раније изразили жељу за храном треба раније да буду опслужени . Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
4. Решити &amp;lt;code&amp;gt;Child Care&amp;lt;/code&amp;gt; проблем користећи &amp;lt;code&amp;gt;ConcurrentLinkedQueue&amp;lt;/code&amp;gt; и друге произвољне синхронизационе директиве. Родитељ доводи једно или више деце у обданиште и чека све док се не појави место, како би оставио сву децу одједном и отишао. Родитељ може и да одведе једно или више деце, такође одједном. Мора се поштовати редослед доласка родитеља који остављају децу и васпитачица које одлазе са посла. Потребно је да програм буде максимално конкурентан и отпоран на прекиде.&lt;br /&gt;
&lt;br /&gt;
== Решење за Atomic Broadcast ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G1;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
&lt;br /&gt;
	private static final int consumersCount=3;&lt;br /&gt;
	private static final int b=5;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
		AtomicInteger[][] reads = new AtomicInteger[b][consumersCount];&lt;br /&gt;
&lt;br /&gt;
		Semaphore mutex = new Semaphore(1);&lt;br /&gt;
&lt;br /&gt;
		AtomicInteger[] buffer = new AtomicInteger[b];&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; buffer.length; i++)&lt;br /&gt;
			buffer[i] = new AtomicInteger(0);&lt;br /&gt;
&lt;br /&gt;
		Consumer[] consumers = new Consumer[consumersCount];&lt;br /&gt;
&lt;br /&gt;
		Producer p = new Producer(consumersCount, buffer, reads,b,mutex);&lt;br /&gt;
		p.start();&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; b; i++)&lt;br /&gt;
			for(int j=0;j&amp;lt;consumersCount;j++)&lt;br /&gt;
				reads[i][j] = new AtomicInteger(0);&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; consumersCount; i++) {&lt;br /&gt;
			consumers[i] = new Consumer(buffer, reads,b,mutex,i);&lt;br /&gt;
			consumers[i].start();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Producer.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G1;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Producer extends Thread {&lt;br /&gt;
&lt;br /&gt;
	private final int consumers;&lt;br /&gt;
	private AtomicInteger[] buffer;&lt;br /&gt;
	private AtomicInteger[][] reads;&lt;br /&gt;
	private Semaphore mutex;&lt;br /&gt;
	private int b;&lt;br /&gt;
&lt;br /&gt;
	public Producer(int consumers, AtomicInteger[] buffer, AtomicInteger[][] reads, int bb, Semaphore mutex) {&lt;br /&gt;
		this.consumers = consumers;&lt;br /&gt;
		this.buffer = buffer;&lt;br /&gt;
		this.reads = reads;&lt;br /&gt;
		b=bb;&lt;br /&gt;
		this.mutex = mutex;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		for (int i = 0; i &amp;lt;b; i++) {&lt;br /&gt;
			for (int j = 0; j &amp;lt; consumers; j++)&lt;br /&gt;
				while(reads[i][j].get() == 1)&lt;br /&gt;
					Thread.onSpinWait();&lt;br /&gt;
&lt;br /&gt;
			int rand = (int)(Math.random() * 10);&lt;br /&gt;
			System.out.println(&amp;quot;Producer produced element: &amp;quot; + rand );&lt;br /&gt;
			mutex.acquireUninterruptibly();&lt;br /&gt;
			buffer[i].set(rand);&lt;br /&gt;
			mutex.release();&lt;br /&gt;
&lt;br /&gt;
			mutex.acquireUninterruptibly();&lt;br /&gt;
			for (int j2 = 0; j2 &amp;lt; consumers; j2++)&lt;br /&gt;
				reads[i][j2].set(0);&lt;br /&gt;
&lt;br /&gt;
			mutex.release();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Consumer.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G1;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Consumer extends Thread {&lt;br /&gt;
&lt;br /&gt;
	private int id;&lt;br /&gt;
	private AtomicInteger[][] reads;&lt;br /&gt;
	private AtomicInteger[] buffer;&lt;br /&gt;
	private Semaphore mutex;&lt;br /&gt;
	private int b;&lt;br /&gt;
&lt;br /&gt;
	public Consumer(AtomicInteger[] buff, AtomicInteger[][] r, int bb,Semaphore mutex, int i) {&lt;br /&gt;
		buffer = buff;&lt;br /&gt;
		reads=r;&lt;br /&gt;
		id=i;&lt;br /&gt;
		this.mutex = mutex;&lt;br /&gt;
		b=bb;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		for (int i = 0; i &amp;lt; b; i++) {&lt;br /&gt;
			while(reads[i][id].get() == 1)&lt;br /&gt;
				Thread.onSpinWait();&lt;br /&gt;
			mutex.acquireUninterruptibly();&lt;br /&gt;
			int elem = buffer[i].get();&lt;br /&gt;
			System.out.println(&amp;quot;Consumer &amp;quot;+id+&amp;quot; consumed element &amp;quot;+elem +&amp;quot;from place &amp;quot;+i);&lt;br /&gt;
			reads[i][id].set(1);&lt;br /&gt;
			mutex.release();&lt;br /&gt;
&lt;br /&gt;
			try {&lt;br /&gt;
				sleep((int)(Math.random()*2000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				throw new RuntimeException(e);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Решење за H2O ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.CyclicBarrier;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		int cnt = 10;&lt;br /&gt;
		&lt;br /&gt;
		Barrier barrier = new Barrier(new CyclicBarrier(3));&lt;br /&gt;
		&lt;br /&gt;
		Hydrogen[] h = new Hydrogen[cnt*2];&lt;br /&gt;
		Oxygen[] o = new Oxygen[cnt];&lt;br /&gt;
		&lt;br /&gt;
		for(int i = 0; i &amp;lt; cnt; i++) {&lt;br /&gt;
			o[i] = new Oxygen(barrier);&lt;br /&gt;
			h[2*i] = new Hydrogen(barrier);	&lt;br /&gt;
			h[2*i + 1] = new Hydrogen(barrier);	&lt;br /&gt;
			&lt;br /&gt;
			o[i].start();&lt;br /&gt;
			h[2*i].start();&lt;br /&gt;
			h[2*i+1].start();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== &amp;lt;code&amp;gt;Oxygen.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.BrokenBarrierException;&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
&lt;br /&gt;
public class Oxygen extends Thread {&lt;br /&gt;
	&lt;br /&gt;
	Barrier barrier;&lt;br /&gt;
	&lt;br /&gt;
	Oxygen(Barrier b){&lt;br /&gt;
		barrier = b;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep((int)(Math.random() * 4000));&lt;br /&gt;
			} catch (InterruptedException e) {}&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			barrier.oxygen.acquireUninterruptibly();&lt;br /&gt;
&lt;br /&gt;
			barrier.oCount++;&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
				System.out.println(&amp;quot;Kiseonik pristigao na barijeru&amp;quot;);&lt;br /&gt;
				&lt;br /&gt;
				if(barrier.barrier.await() == 0) {&lt;br /&gt;
					System.out.println(&amp;quot;\nFORMIRANJE VODE!\n&amp;quot;);&lt;br /&gt;
					&lt;br /&gt;
					barrier.hCount = 0;&lt;br /&gt;
					barrier.oCount = 1;&lt;br /&gt;
					&lt;br /&gt;
					barrier.hydrogen.release(2);&lt;br /&gt;
					barrier.oxygen.release(1);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
			} catch (InterruptedException | BrokenBarrierException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Hydrogen.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.BrokenBarrierException;&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
&lt;br /&gt;
public class Hydrogen extends Thread {&lt;br /&gt;
	&lt;br /&gt;
	Barrier barrier;&lt;br /&gt;
	&lt;br /&gt;
	Hydrogen(Barrier b){&lt;br /&gt;
		barrier = b;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep((int)(Math.random() * 4000));&lt;br /&gt;
			} catch (InterruptedException e) {}&lt;br /&gt;
			&lt;br /&gt;
			barrier.hydrogen.acquireUninterruptibly();&lt;br /&gt;
&lt;br /&gt;
			barrier.hCount++;&lt;br /&gt;
			&lt;br /&gt;
			try {&lt;br /&gt;
				System.out.println(&amp;quot;Vodonik pristigao na barijeru&amp;quot;);&lt;br /&gt;
				&lt;br /&gt;
				if(barrier.barrier.await() == 0) {&lt;br /&gt;
					System.out.println(&amp;quot;\nFORMIRANJE VODE!\n&amp;quot;);&lt;br /&gt;
					barrier.hCount = 0;&lt;br /&gt;
					barrier.oCount = 1;&lt;br /&gt;
					&lt;br /&gt;
					barrier.hydrogen.release(2);&lt;br /&gt;
					barrier.oxygen.release(1);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
			} catch (InterruptedException | BrokenBarrierException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Barrier.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package H20;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.CyclicBarrier;&lt;br /&gt;
import java.util.concurrent.Semaphore;&lt;br /&gt;
&lt;br /&gt;
public class Barrier {&lt;br /&gt;
	CyclicBarrier barrier;&lt;br /&gt;
	Semaphore hydrogen, oxygen;&lt;br /&gt;
	int hCount, oCount;&lt;br /&gt;
	&lt;br /&gt;
	Barrier(CyclicBarrier cb){&lt;br /&gt;
		barrier = cb;&lt;br /&gt;
		hCount = 0;&lt;br /&gt;
		oCount = 0;&lt;br /&gt;
		hydrogen = new Semaphore(2);&lt;br /&gt;
		oxygen = new Semaphore(1);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Решење за Dining Philosophers ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G3;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
&lt;br /&gt;
	public static final int N = 5;&lt;br /&gt;
&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
		Philosopher[] philosophers = new Philosopher[N];&lt;br /&gt;
		AtomicInteger[] forks = new AtomicInteger[N];&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; forks.length; i++)&lt;br /&gt;
			forks[i] = new AtomicInteger(1);&lt;br /&gt;
&lt;br /&gt;
		Table table = new Table();&lt;br /&gt;
&lt;br /&gt;
		for (int i = 0; i &amp;lt; N; i++) {&lt;br /&gt;
			philosophers[i] = new Philosopher(forks, i, N, table);&lt;br /&gt;
			philosophers[i].start();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== &amp;lt;code&amp;gt;Table.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G3;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Table {&lt;br /&gt;
&lt;br /&gt;
	AtomicInteger ticket;&lt;br /&gt;
	int next;&lt;br /&gt;
&lt;br /&gt;
	public Table() {&lt;br /&gt;
		ticket = new AtomicInteger(0);&lt;br /&gt;
		next = 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Philosopher.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package rs.ac.bg.etf.kdp.lab12024G3;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
&lt;br /&gt;
public class Philosopher extends Thread {&lt;br /&gt;
&lt;br /&gt;
	AtomicInteger[] forks;&lt;br /&gt;
	int id,left,right,N,myTicket;&lt;br /&gt;
	Table t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public Philosopher(AtomicInteger[] forks, int id, int n,Table table) {&lt;br /&gt;
		this.forks = forks;&lt;br /&gt;
		this.id = id;&lt;br /&gt;
		N = n;&lt;br /&gt;
		left = id;&lt;br /&gt;
		right = (id+1)%n;&lt;br /&gt;
		t = table;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@Override&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			int choice = (int)(Math.random() * 2);&lt;br /&gt;
&lt;br /&gt;
			switch (choice) {&lt;br /&gt;
			case 0: {&lt;br /&gt;
				eat();&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			case 1:{&lt;br /&gt;
				think();&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			default:&lt;br /&gt;
				throw new IllegalArgumentException(&amp;quot;Unexpected value: &amp;quot; + choice);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public void think() {&lt;br /&gt;
		System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; thinking&amp;quot;);&lt;br /&gt;
		try {&lt;br /&gt;
			sleep((int)(Math.random() * 3000));&lt;br /&gt;
		} catch (InterruptedException e) {&lt;br /&gt;
			// TODO Auto-generated catch block&lt;br /&gt;
			e.printStackTrace();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	public void eat() {&lt;br /&gt;
		myTicket = t.ticket.getAndIncrement();&lt;br /&gt;
		synchronized (forks) {&lt;br /&gt;
&lt;br /&gt;
			System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; wants to eat&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
			while(forks[left].intValue() == 0 || forks[right].intValue() == 0 || myTicket != t.next)&lt;br /&gt;
				try {&lt;br /&gt;
					forks.wait();&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					// TODO Auto-generated catch block&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
			System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; started eating&amp;quot;);&lt;br /&gt;
			t.next++;&lt;br /&gt;
			forks[left].set(0);&lt;br /&gt;
			forks[right].set(0);&lt;br /&gt;
&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		try {&lt;br /&gt;
			sleep((int)(Math.random() * 2000));&lt;br /&gt;
		} catch (InterruptedException e) {&lt;br /&gt;
			// TODO Auto-generated catch block&lt;br /&gt;
			e.printStackTrace();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		synchronized (forks) {&lt;br /&gt;
&lt;br /&gt;
			System.out.println(&amp;quot;Philosopher &amp;quot;+id+&amp;quot; finished eating&amp;quot;);&lt;br /&gt;
			forks[left].set(1);&lt;br /&gt;
			forks[right].set(1);&lt;br /&gt;
			forks.notifyAll();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Решење за Child Care ==&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Test.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class Test {&lt;br /&gt;
	public static void main(String[] args) {&lt;br /&gt;
		Kindergarten k = new Kindergarten(12);&lt;br /&gt;
		k.startProgram(4, 3);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== &amp;lt;code&amp;gt;Kindergarten.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.ConcurrentLinkedQueue;&lt;br /&gt;
&lt;br /&gt;
public class Kindergarten {&lt;br /&gt;
	int childrenInside = 0;&lt;br /&gt;
	int teachersInside = 0;&lt;br /&gt;
	int capacity;&lt;br /&gt;
	public ConcurrentLinkedQueue&amp;lt;Integer&amp;gt; parentQueue;&lt;br /&gt;
	public ConcurrentLinkedQueue&amp;lt;Integer&amp;gt; teacherQueue;&lt;br /&gt;
	public Kindergarten(int capacity) { &lt;br /&gt;
		parentQueue = new ConcurrentLinkedQueue&amp;lt;Integer&amp;gt;();&lt;br /&gt;
		teacherQueue = new ConcurrentLinkedQueue&amp;lt;Integer&amp;gt;();&lt;br /&gt;
		this.capacity = capacity;&lt;br /&gt;
	}&lt;br /&gt;
	public static boolean ruleFollowed(int teachers, int children, int capacity ) {&lt;br /&gt;
		if(teachers == 0 || children &amp;gt; capacity) return false;&lt;br /&gt;
		return teachers &amp;gt;= Math.ceil(children / 3.0);&lt;br /&gt;
	}&lt;br /&gt;
	public void startProgram(int teachersUsed, int parentsUsed) {&lt;br /&gt;
		Teacher[] teachers = new Teacher[teachersUsed];&lt;br /&gt;
		Parent[] parents = new Parent[parentsUsed];&lt;br /&gt;
		for(int i = 0; i &amp;lt; teachersUsed; i++) {&lt;br /&gt;
			teachers[i] = new Teacher(i, this);&lt;br /&gt;
			teachers[i].start();&lt;br /&gt;
		}&lt;br /&gt;
		for(int i = 0; i &amp;lt; parentsUsed; i++) {&lt;br /&gt;
			parents[i] = new Parent(i, this);&lt;br /&gt;
			parents[i].start();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Teacher.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
import java.util.Random;&lt;br /&gt;
import java.util.concurrent.ConcurrentLinkedQueue;&lt;br /&gt;
&lt;br /&gt;
public class Teacher extends Thread {&lt;br /&gt;
	Kindergarten k;&lt;br /&gt;
	int id;&lt;br /&gt;
	&lt;br /&gt;
	public Teacher(int id, Kindergarten k) {&lt;br /&gt;
		this.k = k;&lt;br /&gt;
		this.id = id;&lt;br /&gt;
	}&lt;br /&gt;
	public void run() {&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			synchronized(k) {&lt;br /&gt;
				k.teachersInside++;&lt;br /&gt;
				System.out.println(&amp;quot;Teacher &amp;quot; + id + &amp;quot; came to work.&amp;quot;);&lt;br /&gt;
				k.notifyAll();&lt;br /&gt;
			}&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			synchronized(k) {&lt;br /&gt;
				k.teacherQueue.add(id);&lt;br /&gt;
				System.out.println(&amp;quot;Teacher &amp;quot; + id + &amp;quot; wishes to leave work.&amp;quot;);&lt;br /&gt;
				while(!(k.teacherQueue.element() == id &amp;amp;&amp;amp; Kindergarten.ruleFollowed(k.teachersInside - 1, k.childrenInside, k.capacity))) {&lt;br /&gt;
					try {&lt;br /&gt;
						k.wait();&lt;br /&gt;
					} catch (InterruptedException e) {&lt;br /&gt;
						e.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				System.out.println(&amp;quot;Teacher &amp;quot; + id + &amp;quot; has left work.&amp;quot;);&lt;br /&gt;
				k.teachersInside--;&lt;br /&gt;
				k.teacherQueue.remove();&lt;br /&gt;
				k.notifyAll();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;Parent.java&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package ChildCare;&lt;br /&gt;
&lt;br /&gt;
import java.util.Random;&lt;br /&gt;
import java.util.concurrent.ConcurrentLinkedQueue;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
public class Parent extends Thread {&lt;br /&gt;
	&lt;br /&gt;
	boolean interacted = false;&lt;br /&gt;
	Kindergarten k;&lt;br /&gt;
	int id;&lt;br /&gt;
	public Parent(int id, Kindergarten k) {&lt;br /&gt;
		this.k = k;&lt;br /&gt;
		this.id = id;&lt;br /&gt;
	}&lt;br /&gt;
	public void run() {&lt;br /&gt;
		&lt;br /&gt;
		while(true) {&lt;br /&gt;
			try {&lt;br /&gt;
				Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
			} catch (InterruptedException e) {&lt;br /&gt;
				e.printStackTrace();&lt;br /&gt;
			}&lt;br /&gt;
			int childrenBrought = 1 + new Random().nextInt(4);&lt;br /&gt;
			System.out.println(&amp;quot;Parent &amp;quot; + id + &amp;quot; brought &amp;quot; + childrenBrought + &amp;quot; children.&amp;quot;);&lt;br /&gt;
			interacted = false;&lt;br /&gt;
&lt;br /&gt;
			synchronized(k) {&lt;br /&gt;
				k.parentQueue.add(id);&lt;br /&gt;
				while(!(k.parentQueue.peek() == id &amp;amp;&amp;amp; Kindergarten.ruleFollowed(k.teachersInside, k.childrenInside + childrenBrought, k.capacity))) {&lt;br /&gt;
					try {&lt;br /&gt;
						k.wait();&lt;br /&gt;
					} catch (InterruptedException e) {&lt;br /&gt;
						e.printStackTrace();&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
				k.parentQueue.remove();&lt;br /&gt;
				k.childrenInside += childrenBrought;&lt;br /&gt;
				System.out.println(&amp;quot;Parent &amp;quot; + id + &amp;quot; left his &amp;quot; + childrenBrought + &amp;quot; children.&amp;quot;);&lt;br /&gt;
				k.notifyAll();&lt;br /&gt;
			}&lt;br /&gt;
			while(childrenBrought &amp;gt; 0) {&lt;br /&gt;
				try {&lt;br /&gt;
					Thread.sleep(new Random().nextInt(5000));&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
				int childrenToPickUp = 1 + (1 + new Random().nextInt(4)) % childrenBrought;&lt;br /&gt;
				synchronized(k) {&lt;br /&gt;
					k.childrenInside -= childrenToPickUp;&lt;br /&gt;
					System.out.println(&amp;quot;Parent &amp;quot; + id + &amp;quot; took home his &amp;quot; + childrenToPickUp + &amp;quot;/&amp;quot; + childrenBrought + &amp;quot; children.&amp;quot;);&lt;br /&gt;
					k.notifyAll();&lt;br /&gt;
				}&lt;br /&gt;
				childrenBrought -= childrenToPickUp;&lt;br /&gt;
			}&lt;br /&gt;
		&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категорија:КДП]]&lt;br /&gt;
[[Категорија:Лабораторијске вежбе]]&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Ralepop&amp;diff=8208</id>
		<title>Корисник:Ralepop</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Ralepop&amp;diff=8208"/>
		<updated>2025-12-06T03:34:48Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: Ralepop преместио је страницу Корисник:Ralepop на Корисник:Elar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#Преусмери [[Корисник:Elar]]&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=8207</id>
		<title>Корисник:Elar</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=8207"/>
		<updated>2025-12-06T03:34:48Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: Ralepop преместио је страницу Корисник:Ralepop на Корисник:Elar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;unpaid-lilac-gizmo@duck.com&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=8206</id>
		<title>Корисник:Elar</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=8206"/>
		<updated>2025-12-06T03:31:40Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;unpaid-lilac-gizmo@duck.com&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%98%D0%BD%D1%82%D0%B5%D0%BB%D0%B8%D0%B3%D0%B5%D0%BD%D1%82%D0%BD%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B8&amp;diff=8204</id>
		<title>Интелигентни системи</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%98%D0%BD%D1%82%D0%B5%D0%BB%D0%B8%D0%B3%D0%B5%D0%BD%D1%82%D0%BD%D0%B8_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B8&amp;diff=8204"/>
		<updated>2025-12-05T20:04:43Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: /* Настава */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Предмет&lt;br /&gt;
| шифра     = 13С113ИС, 13E114ИС&lt;br /&gt;
| семестар  = 5 (СИ), 7&lt;br /&gt;
| статус    = изборни&lt;br /&gt;
| страница  = [http://ri4es.etf.bg.ac.rs/ ri4es.etf.rs]&lt;br /&gt;
| одсек     = СИ, РТИ&lt;br /&gt;
}}&lt;br /&gt;
&#039;&#039;&#039;Интелигентни системи&#039;&#039;&#039; је изборни предмет из петог и седмог семестра за СИ, а само седмог за РТИ.&lt;br /&gt;
&lt;br /&gt;
== Корисне везе ==&lt;br /&gt;
* [https://jetbrains.com/pycharm/ PyCharm] — развојно окружење за &#039;&#039;Python&#039;&#039;&lt;br /&gt;
* [https://app.box.com/s/0r50je333z1qyypz0h3rm0iqb9s0d64f/folder/38795524647 ETF Materijali (Box)] (рокови)&lt;br /&gt;
&lt;br /&gt;
== Настава ==&lt;br /&gt;
Области су подељене у три блока на предавањима и вежбама, које долазе редом на колоквијумима:&lt;br /&gt;
* &#039;&#039;&#039;Први блок:&#039;&#039;&#039; алгоритми претраживања, методи задовољења ограничења&lt;br /&gt;
* &#039;&#039;&#039;Други блок:&#039;&#039;&#039; теорија игара - симултане игре и секвенцијалне игре, продукциони системи (само на предавањима), рад у неизвесном окружењу&lt;br /&gt;
* &#039;&#039;&#039;Трећи блок:&#039;&#039;&#039; машинско учење (надгледано, ненадгледано и учење са подршком)&lt;br /&gt;
Вежбе су потребне за колоквијуме, домаће задатке и део испита са задацима. Предавања су потребна за део испита са теоријом, али домаћи задаци могу да замене тај део бодова и генерално су занимљивији. Презентације са [http://ri4es.etf.bg.ac.rs/vezbe.html вежби] и [http://ri4es.etf.bg.ac.rs/predavanja.html предавања] су доступна са странице предмета.&lt;br /&gt;
&lt;br /&gt;
== Домаћи ==&lt;br /&gt;
Домаћи задаци на предмету нису обавезни, али могу да замене бодове са теоријског дела испита и тиме ослободе студента од слушања предавања. Имају три домаћа задатка, по један за сваки блок наставе, сваки по 10 бодова. Пошто теорија на испиту носи 20 бодова, студенти морају да бирају која два домаћа задатка ће радити и бранити. Домаћи задаци се раде у &#039;&#039;Python&#039;&#039;. Део окружења који нема везе са суштином задатка је већ дат, и студентима је дато да имплементирају суштину, односно интелигенцију у задатку. Студентима уз поставку буде дата нека врста јавних тестова за своје домаће, док се на одбрани домаћи тестирају са неком врстом тајних тестова чисто како би се проверило да ли они раде ван тестова на којим је студент пробао. Додатан рад на опционалним стварима попут графичког корисничког интерфејса може бити награђен којим бодом преко максимума. Школске 2023/24. године, додатни поени су се добијали за истакнуте перформансе или кроз међусобно тачмичење алгоритама.&lt;br /&gt;
&lt;br /&gt;
Стари домаћи задаци доступни су са [http://ri4es.etf.bg.ac.rs/projekat.html странице предмета].&lt;br /&gt;
&lt;br /&gt;
Примери модификација за домаће задатке из школске 2023/24 се могу се наћи на [[Интелигентни_системи/Домаћи_2023|следећој страници]].&lt;br /&gt;
&lt;br /&gt;
== Испитни рокови ==&lt;br /&gt;
На страници предмета нису доступни старији рокови, јер су задаци који су били релевантни са старих рокова издвојени на презентације са вежби. Неки старији рокови се могу наћи на драјву у одељку за [[#Корисне везе|корисне везе]].&lt;br /&gt;
&lt;br /&gt;
=== Колоквијум 1===&lt;br /&gt;
{{#dpl:&lt;br /&gt;
| titleregexp     = Интелигентни_системи/К1&lt;br /&gt;
| noresultsheader = Тренутно нема сачуваних рокова.&lt;br /&gt;
| format          = ,\n* [[%PAGE%|²{#invoke:String¦sub¦%PAGE%¦22¦-1}²]],,&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Колоквијум 2===&lt;br /&gt;
{{#dpl:&lt;br /&gt;
| titleregexp     = Интелигентни_системи/К2&lt;br /&gt;
| noresultsheader = Тренутно нема сачуваних рокова.&lt;br /&gt;
| format          = ,\n* [[%PAGE%|²{#invoke:String¦sub¦%PAGE%¦22¦-1}²]],,&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Колоквијум ===&lt;br /&gt;
{{#dpl:&lt;br /&gt;
| titleregexp     = Интелигентни_системи/К&lt;br /&gt;
| noresultsheader = Тренутно нема сачуваних рокова.&lt;br /&gt;
| format          = ,\n* [[%PAGE%|²{#invoke:String¦sub¦%PAGE%¦22¦-1}²]],,&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Испит ===&lt;br /&gt;
{{#dpl:&lt;br /&gt;
| titleregexp     = Интелигентни_системи/.* \d+$&lt;br /&gt;
| nottitleregexp  = Интелигентни_системи/К\d&lt;br /&gt;
| nottitleregexp  = Интелигентни_системи/К&lt;br /&gt;
| nottitleregexp  = Интелигентни_системи/Домаћи&lt;br /&gt;
| noresultsheader = Тренутно нема сачуваних рокова.&lt;br /&gt;
| format          = ,\n* [[%PAGE%|²{#invoke:String¦sub¦%PAGE%¦22¦-1}²]],,&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Начин оцењивања ==&lt;br /&gt;
* &amp;lt;math&amp;gt;K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;K_2&amp;lt;/math&amp;gt; — бодови са првог и другог колоквијума (0-25, могу се поправити у сваком року с тим што освојени бодови на поправкама важе само у року у којем је рађена поправка) - на РТИ ово представља један колоквијум који вреди 50 поена&lt;br /&gt;
* &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; — укупни бодови са домаћих задатака (0-20)&lt;br /&gt;
* &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; — бодови са трећег колоквијума, односно делу испита са задацима (0-30)&lt;br /&gt;
* &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; — бодови са теоријског дела испита (0-20), ако је започето решавање, гледа се само то&lt;br /&gt;
* Бодови: &amp;lt;math&amp;gt;P = K_1 + K_2 + OR \left(T, D\right) + I&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
У сваком року могуће је радити било коју комбинацију [К1+К2+И, К1+И, К2+И, И, К+И] и уз сваки од њих могуће је радити теорију која мења домаће задатке. Ако се ради теорија, она у потпуности мења домаће задатке (није могуће радити један домаћи и једно теоријско питање). &#039;&#039;&#039;Поени ни са једног дела испита се не преносе у наредне испитне рокове, која год комбинација да се ради.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Бодови&lt;br /&gt;
| &amp;lt;math&amp;gt;P \leq 50&amp;lt;/math&amp;gt; || &amp;lt;math&amp;gt;50 &amp;lt; P \leq 60&amp;lt;/math&amp;gt; || &amp;lt;math&amp;gt;60 &amp;lt; P \leq 70&amp;lt;/math&amp;gt; || &amp;lt;math&amp;gt;70 &amp;lt; P \leq 80&amp;lt;/math&amp;gt; || &amp;lt;math&amp;gt;80 &amp;lt; P \leq 90&amp;lt;/math&amp;gt; || &amp;lt;math&amp;gt;90 &amp;lt; P&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Оцена&lt;br /&gt;
| 5 || 6 || 7 || 8 || 9 || 10&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Потребна помоћ ==&lt;br /&gt;
* {{zadaci|postavke}}&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=8203</id>
		<title>Корисник:Elar</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=8203"/>
		<updated>2025-12-05T00:00:38Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;rale@keemail.me&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=7941</id>
		<title>Корисник:Elar</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D0%BD%D0%B8%D0%BA:Elar&amp;diff=7941"/>
		<updated>2025-08-17T23:41:25Z</updated>

		<summary type="html">&lt;p&gt;Ralepop: Нова страница: SI&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SI&lt;/div&gt;</summary>
		<author><name>Ralepop</name></author>
	</entry>
</feed>