Cześć, na wstępie napiszę, że szukałem podobnego tematu, ale nic się nie przydało.
Mam do napisania program, gdzie pasażerowie przechodzą przez most na statek. Most ma pewną przepustowość K, a statek pojemność N > K. Statek odpływa co godzinę, a kapitan musi dopilnować, żeby w tym czasie nie było na moście wchodzącego
pasażera. Oczywiście na moście nie może być więcej osób niż K, a na statku więcej niż N.
Mam następujący problem: powołuję co losowy czas nowe wątki Pasażera, które podczas wchodzenia na most opuszczają semafory Mostu i Statku, ale czasami pojawia się problem, że wszystkie naraz wchodzą na most, przekraczając tym samym pojemność Statku i blokując program...
Niestety słabo jeszcze rozumiem tą współbieżność.
////////////////////////////Metoda run() klasy Pasażer
public synchronized void run() {
try {
while(!passed){ //warunek czy pasażer już przeszedł przez most
if (s.isOpened()){ //sprawdzam czy statek jest w porcie
if (s.getPermits() > 0){ //sprawdzam czy na statku są jeszcze wolne miejsca
synchronized (l){ //wg mnie w tej sekcji jest problem
b.acquireSemaphore();
s.acquireSemaphore();
}
TimeUnit.MILLISECONDS.sleep(rand.nextInt(4000));
b.releaseSemaphore();
passed = true;
}
else{
TimeUnit.SECONDS.sleep(1);
System.out.println("Pasażer " + passengerID
+ " czeka na kolejną turę, brak miejsc.");
}
}else{
TimeUnit.SECONDS.sleep(1);
System.out.println("Pasażer " + passengerID
+ " czeka na przybycie statku");
}
}
} catch (InterruptedException e) { e.printStackTrace(); }
}
//////////////////////////////////////KLASA STATEK
private static Semaphore shipSemaphore;
private static ReentrantLock shipLock = new ReentrantLock();
public synchronized void acquireSemaphore() throws InterruptedException{ Ship.shipSemaphore.acquireUninterruptibly(); }
public synchronized void releaseSemaphore(){ Ship.shipSemaphore.release(); }
public synchronized void lock(){
try {
Ship.shipLock.lockInterruptibly();
} catch (InterruptedException e) { System.out.println("Nie mozna wykonac: Bridge.bridgeLock.lockInterruptibly()");}
}
//////////////////////////////////////KLASA MOST
private static Semaphore bridgeSemaphore;
public synchronized void acquireSemaphore() throws InterruptedException { Bridge.bridgeSemaphore.acquireUninterruptibly(); }
public void releaseSemaphore(){ Bridge.bridgeSemaphore.release(); }