1 | Tennis tournament
|
---|
2 | Потребно е да направите сценарио за синхронизација на турнир во тенис за двојки.
|
---|
3 |
|
---|
4 | На турнирот се натпреваруваат зелена со црвена група, каде во секоја од групите има по 30 учесници.
|
---|
5 |
|
---|
6 | Потребно е да го синхронизирате турнирот на следниот начин:
|
---|
7 |
|
---|
8 | По стартувањето на играчите во позадина, тие најпрво треба да испечатат {Red|Green} player ready
|
---|
9 | На теренот може да влезат по 2 играчи од двете групи. По влегувањето треба да испечатат {Red|Geen} player enters field
|
---|
10 | Доколку влезат повеќе од 2 играчи од некоја од групте, сценариото е невалидно
|
---|
11 | Откако ќе влезат четирите играчи на теренот, треба истовремено да започнат со играта со печатење на Match started и повикување на Thread.sleep(200)
|
---|
12 | Треба да се повика истовремено и паралелно да се повика кај сите играчи.
|
---|
13 | Откако ќе заврши Thread.sleep кај сите играчи сите печатат {Red|Green} player finished playing
|
---|
14 | Потоа само еден играч печати Match finished и сигнализира дека теренот е слободен.
|
---|
15 | Потребно е да имплементирате сценарио во кое во main методот ќе се стартуваат по 30 инстанци од класите Greenplayer и Redplayer кои ќе се однесуваат како Threads и во позадина секоја ќе знае да изигра една партија според претходно опишаното сценарио. Откако сите играчи ќе се стартуваат, треба за секој од нив да се почека да заврши за максимум 1 секунда (1000 ms). Потоа треба да се провери дали сите инстанци се завршени со позадинското извршување. Доколку некоја инстанца не е завршена, потребно е истата да се терминира и да се испечати пораката: Possible deadlock.
|
---|
16 |
|
---|
17 | Имплементацијата на сценариото треба да се направи во execute методите, кои треба да се стартуваат во позадина.
|
---|
18 |
|
---|
19 |
|
---|
20 | import java.util.HashSet;
|
---|
21 | import java.util.concurrent.Semaphore;
|
---|
22 |
|
---|
23 | public class TennisTournament {
|
---|
24 |
|
---|
25 |
|
---|
26 | static int greenNum = 0;
|
---|
27 | static Semaphore lock = new Semaphore(1);
|
---|
28 |
|
---|
29 | static Semaphore red = new Semaphore(2);
|
---|
30 | static Semaphore green = new Semaphore(2);
|
---|
31 |
|
---|
32 | static Semaphore redHere = new Semaphore(0);
|
---|
33 | static Semaphore ready = new Semaphore(0);
|
---|
34 |
|
---|
35 | static Semaphore done = new Semaphore(0);
|
---|
36 |
|
---|
37 |
|
---|
38 | public static class GreenPlayer extends Thread {
|
---|
39 |
|
---|
40 | @Override
|
---|
41 | public void run() {
|
---|
42 | try {
|
---|
43 | execute();
|
---|
44 | } catch (InterruptedException e) {
|
---|
45 | e.printStackTrace();
|
---|
46 | }
|
---|
47 | }
|
---|
48 |
|
---|
49 | public void execute() throws InterruptedException {
|
---|
50 | System.out.println("Green player ready");
|
---|
51 | green.acquire();
|
---|
52 | System.out.println("Green player enters field");
|
---|
53 | lock.acquire();
|
---|
54 | greenNum++;
|
---|
55 | if (greenNum == 2) {
|
---|
56 | lock.release();
|
---|
57 | redHere.acquire(2);
|
---|
58 | ready.release(4);
|
---|
59 | } else {
|
---|
60 | lock.release();
|
---|
61 | }
|
---|
62 | ready.acquire();
|
---|
63 | System.out.println("Match started");
|
---|
64 | Thread.sleep(200);
|
---|
65 | System.out.println("Green player finished playing");
|
---|
66 | done.release();
|
---|
67 |
|
---|
68 | lock.acquire();
|
---|
69 | greenNum--;
|
---|
70 | if (greenNum == 0) {
|
---|
71 |
|
---|
72 | done.acquire(4);
|
---|
73 | // TODO: only one player calls the next line per match
|
---|
74 | System.out.println("Match finished");
|
---|
75 | green.release(2);
|
---|
76 | red.release(2);
|
---|
77 | }
|
---|
78 | lock.release();
|
---|
79 | }
|
---|
80 |
|
---|
81 | }
|
---|
82 |
|
---|
83 | public static class RedPlayer extends Thread {
|
---|
84 |
|
---|
85 | @Override
|
---|
86 | public void run() {
|
---|
87 | try {
|
---|
88 | execute();
|
---|
89 | } catch (InterruptedException e) {
|
---|
90 | e.printStackTrace();
|
---|
91 | }
|
---|
92 | }
|
---|
93 |
|
---|
94 | public void execute() throws InterruptedException {
|
---|
95 | System.out.println("Red player ready");
|
---|
96 | red.acquire();
|
---|
97 | System.out.println("Red player enters field");
|
---|
98 | redHere.release();
|
---|
99 | ready.acquire();
|
---|
100 | System.out.println("Match started");
|
---|
101 | Thread.sleep(200);
|
---|
102 | System.out.println("Red player finished playing");
|
---|
103 | done.release();
|
---|
104 | }
|
---|
105 |
|
---|
106 | }
|
---|
107 |
|
---|
108 | public static void main(String[] args) throws InterruptedException {
|
---|
109 | // start 30 red and 30 green players in background
|
---|
110 | HashSet<Thread> threads = new HashSet<Thread>();
|
---|
111 | for (int i = 0; i < 30; i++) {
|
---|
112 | RedPlayer red = new RedPlayer();
|
---|
113 | threads.add(red);
|
---|
114 | GreenPlayer green = new GreenPlayer();
|
---|
115 | threads.add(green);
|
---|
116 | }
|
---|
117 | for (Thread t : threads) {
|
---|
118 | t.start();
|
---|
119 | }
|
---|
120 | // after all of them are started, wait each of them to finish for 1_000 ms
|
---|
121 | for (Thread t : threads) {
|
---|
122 | t.join(2_000);
|
---|
123 | }
|
---|
124 | // after the waiting for each of the players is done, check the one that are not finished and terminate them
|
---|
125 | for (Thread t : threads) {
|
---|
126 | if (t.isAlive()) {
|
---|
127 | t.interrupt();
|
---|
128 | System.err.println("POSSIBLE DEADLOCK!");
|
---|
129 | }
|
---|
130 | }
|
---|
131 |
|
---|
132 | }
|
---|
133 |
|
---|
134 | } |
---|