I have here an exercise called Parking. I understand slightly, but there is one thing that is not clear to me, and I mean the parameter that takes Semaphore sem = new Semaphore(este_parametro_me_refiero)
. I appreciate the help! She left you the code:
package ejercicio6_Parking;
import java.util.concurrent.Semaphore;
public class Coche implements Runnable{
private Semaphore sem;
private int numeroCoche;
public Coche(int numeroCoche, Semaphore sem) {
this.numeroCoche = numeroCoche;
this.sem = sem;
}
@Override
public void run() {
System.out.println("Arranca el coche " + numeroCoche);
while(true) {
//el coche va por la ciudad entre 1 y 30s e intenta entrar al parking
try {
Thread.sleep( (long) (Math.random()*30000) );
System.out.println("El coche " + numeroCoche + " llega al parking e intenta entrar.");
sem.acquire();
System.out.println("El coche " + numeroCoche + " entra.");
Thread.sleep( (long) (Math.random()*30000));
System.out.println("El coche " + numeroCoche + " sale.");
System.out.println(sem.availablePermits() + " plazas libres.");
System.out.println(sem.getQueueLength() + " coches en la cola.");
sem.release();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
package ejercicio6_Parking;
import java.util.concurrent.Semaphore;
public class Principal {
public static void main(String[] args) {
Semaphore sem = new Semaphore(0);
for(int i=0; i<40; i++) {
Coche c = new Coche(i+1, sem);
Thread th = new Thread(c);
th.start();
}
}
}
The initialization parameter of that class, which indicates the number of times it will allow access to the parking in this case (called without blocking a
acquire
), if you put 2, it will allow the method to be calledacquire
2 times, which will allow 2 cars to pass, once that those 2 cars have occupied the spaces, the next calls will block the threads and wait for the release call of the threads that occupied the parking spaces, which, let's say, would free the parking spaces.in your main method, you have the for that generates several instances of your Car class, which contain the run method, and each car you pass the same instance of
sem
inside the run method, in your class
Coche
,when each instance manages to call the instruction
sem.acquire();
, two things can happen, get a blocking call (that the semaphore does not have "space" to allow that call, incrementing a counter so as not to exceed the numberpermits
that is the initialization parameter of the classSemaphore
) or a non-blocking call (the number of callsacquire
has not exceeded the number ofpermits
). So if I initializeSemaphore sem = new Semaphore(4);
, the first 4 threads that make the call will beacquire
able to continue executing, continue with the instructions belowacquire
, the threads that arrive in 5th, 6th, ... position, will block (they will have to wait for the threads that continued running normally until they reach the callsem.release()
, free spaces in the semaphore), once spaces are freed in the semaphore, the execution of the threads that are waiting can continue, as long as there is "room for them" (non-blocking calls).To begin with, what a semaphore does in java is to allow us to easily give permissions to threads to access resources.
The parameter that you pass to the object
Semaphore
is the number of threads that can simultaneously access a resource. For example, imagine that I want to access a file but I only want a maximum of 4 threads to access it simultaneously. Well, when creating the objectSemaphore
it should be such thatThe
acquire
and methodsrelease
are methods to indicate when a thread is in process and when it has finished in order to allow other threads (if they require it) to access said resource.