import javax.naming.ldap.LdapName;
import java.util.*;
import java.util.concurrent.Semaphore;
public class TancSoStudentite {
//TODO: Definicija na globalni promenlivi i semafori
static Semaphore maski;
static Semaphore zenski;
static Semaphore m_presobleci;
static Semaphore z_presobleci;
static Semaphore parovi;
public void init() {
//TODO: da se implementira
maski = new Semaphore(10);
zenski = new Semaphore(10);
m_presobleci = new Semaphore(0);
z_presobleci = new Semaphore(0);
parovi = new Semaphore(3);
}
class Masko extends Thread {
//TODO: Definicija na promenlivi za sostojbata
public void ucestvo() throws InterruptedException {
//TODO: da se implementira
maski.acquire();
show.presobleci();
parovi.acquire();
m_presobleci.acquire();
z_presobleci.release();
// samo maskoto go povikuva metodot tancuvaj
show.tancuvaj();
maski.release();
parovi.release();
}
@Override
public void run() {
try {
ucestvo();
} catch (InterruptedException e) {
// Do nothing
} catch (Exception e) {
exception = e;
hasException = true;
}
}
@Override
public String toString() {
return String.format("m\t%d", getId());
}
public Exception exception = null;
}
class Zensko extends Thread {
//TODO: Definicija na promenlivi za sostojbata
public void ucestvo() throws InterruptedException {
//TODO: da se implementira
zenski.acquire();
show.presobleci();
m_presobleci.release();
z_presobleci.acquire();
zenski.release();
}
@Override
public void run() {
try {
ucestvo();
} catch (InterruptedException e) {
// Do nothing
} catch (Exception e) {
exception = e;
hasException = true;
}
}
@Override
public String toString() {
return String.format("z\t%d", getId());
}
public Exception exception = null;
}
public static void main(String[] args) {
try {
TancSoStudentite environment = new TancSoStudentite();
environment.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void start() throws Exception {
show = new Show();
init();
HashSet threads = new HashSet();
for (int i = 0; i < BROJ_INSTANCI; i++) {
Zensko z = new Zensko();
Masko m = new Masko();
threads.add(z);
threads.add(m);
}
for (Thread t : threads) {
t.start();
}
boolean valid = true;
for (Thread t : threads) {
if (!hasException) {
t.join();
} else {
t.interrupt();
}
}
show.printStatus();
}
public class Show {
public static final int BROJ_GARDEROBA = 10;
public static final int BROJ_TEREN = 3;
public static final int TYPE_MASKO = 1;
public static final int TYPE_ZENSKO = 2;
public static final int TYPE_UNKNOWN = -1;
public Show() {
}
public int brojMaskiGarderoba = 0;
public int brojZenskiGarderoba = 0;
public int brojTancuvanja = 0;
public int maxMaskiGarderoba = 0;
public int maxZenskiGarderoba = 0;
public int maxTancuvanja = 0;
public void presobleci() throws RuntimeException {
log(null, "presobleci start");
Thread t = Thread.currentThread();
if (t instanceof Masko) {
synchronized (RANDOM) {
brojMaskiGarderoba++;
if (brojMaskiGarderoba > 10) {
exception("Ne moze da ima poveke od 10 maski vo maskata garderoba.");
}
if (brojMaskiGarderoba > maxMaskiGarderoba) {
maxMaskiGarderoba = brojMaskiGarderoba;
}
}
waitRandom();
synchronized (RANDOM) {
brojMaskiGarderoba--;
}
} else {
synchronized (RANDOM) {
brojZenskiGarderoba++;
if (brojZenskiGarderoba > 10) {
exception("Ne moze da ima poveke od 10 zenski vo zenskata garderoba.");
}
if (brojZenskiGarderoba > maxZenskiGarderoba) {
maxZenskiGarderoba = brojZenskiGarderoba;
}
}
waitRandom();
synchronized (RANDOM) {
brojZenskiGarderoba--;
}
}
log(null, "presobleci kraj");
}
public void tancuvaj() throws RuntimeException {
log(null, "tancuvaj start");
synchronized (RANDOM) {
brojTancuvanja++;
if (brojTancuvanja > BROJ_TEREN) {
exception("Ne moze paralelno da tancuvaat poveke od 3 para.");
}
if (brojTancuvanja > maxTancuvanja) {
maxTancuvanja = brojTancuvanja;
}
}
waitRandom();
synchronized (RANDOM) {
brojTancuvanja--;
}
log(null, "tancuvaj kraj");
}
private void waitRandom() {
try {
int r;
synchronized (RANDOM) {
r = RANDOM.nextInt(RANDOM_RANGE);
}
Thread.sleep(r);
} catch (Exception e) {
//do nothing
}
}
private void exception(String message) {
RuntimeException e = new RuntimeException(message);
log(e, null);
hasError = true;
throw e;
}
public int getType() {
Thread t = Thread.currentThread();
if (t instanceof Masko) {
return TYPE_MASKO;
} else if (t instanceof Zensko) {
return TYPE_ZENSKO;
} else {
return TYPE_UNKNOWN;
}
}
private synchronized void log(RuntimeException e, String action) {
Thread t = Thread.currentThread();
if (e == null) {
actions.add(t.toString() + "\t(a): " + action);
} else {
actions.add(t.toString() + "\t(e): " + e.getMessage());
}
}
public synchronized void printLog() {
System.out.println("Poradi konkurentnosta za pristap za pecatenje, mozno e nekoja od porakite da ne e na soodvetnoto mesto.");
System.out.println("Log na izvrsuvanje na akciite:");
System.out.println("=========================");
System.out.println("(tip m<=>Masko, tip z<=>Zensko)");
System.out.println("tip\tid\takcija/error");
System.out.println("=========================");
for (String l : actions) {
System.out.println(l);
}
}
public void printStatus() {
if (!hasError) {
int poeni = 25;
System.out.println("Procesot e uspesno sinhroniziran");
if (show.maxMaskiGarderoba == 1 || show.maxZenskiGarderoba == 1) {
System.out.println("\t-no ima maksimum eden ucesnik vo garderobata.");
poeni -= 5;
}
if (show.maxTancuvanja == 1) {
System.out.println("\t-no ima maksimum edna proverka vo eden moment.");
poeni -= 5;
}
System.out.println("Osvoeni poeni: " + poeni);
} else {
System.out.println("Procesot ne e sinhroniziran spored uslovite na zadacata");
show.printLog();
System.out.println("Maksimum mozni poeni: 15");
}
}
private List actions = new ArrayList();
private boolean hasError = false;
}
// Konstanti
public static int BROJ_INSTANCI = 1000;
public static final Random RANDOM = new Random();
public static final int RANDOM_RANGE = 3;
// Instanca od bafferot
public Show show;
public boolean hasException = false;
}