# Semafori

{% embed url="<https://www.baeldung.com/cs/semaphore>" %}

### Semafori in Java

Utilizzo dei semafori come lock per prevenire le race condition: si possono usare i semafori per bloccare (lock) l'accesso a una risorsa, ogni thread che vuole accedere all'utilizzo della risorsa deve prima chiamare la `acquire()` per prendere il lock. Quando il thread ha ultimato con la risorsa, deve chiamare `release()` per rilasciare il lock. Esempio di utilizzo di `java.util.concurrent.Semaphore`.

```java
package sharedobject;

//A shared resource/class.
public class SharedObject {
    int count = 0;
}

```

```java
package sharedobject;

// java program to demonstrate 
// use of semaphores Locks 

import java.util.concurrent.Semaphore;

class WorkerThread extends Thread
{ 
	Semaphore sem;
	SharedObject sharedObject;

	public WorkerThread(Semaphore sem, SharedObject sharedObject, String threadName)
	{ 
		super(threadName); 
		this.sem = sem;
		this.sharedObject = sharedObject;
	}

	@Override
	public void run() { 
		
		// run by thread A 
		if(this.getName().equals("A")) 
		{ 
			System.out.println("Starting " + getName());
			try
			{ 
				// First, get a permit. 
				System.out.println(getName() + " is waiting for a permit.");
			
				// acquiring the lock 
				sem.acquire(); 
			
				System.out.println(getName() + " gets a permit.");
		
				// Now, accessing the shared resource. 
				// other waiting threads will wait, until this 
				// thread release the lock 
				for(int i=0; i < 5; i++) 
				{ 
					sharedObject.count++;
					System.out.println(getName() + ": " + sharedObject.count);
		
					// Now, allowing a context switch -- if possible. 
					// for thread B to execute 
					Thread.sleep(10); 
				} 
			} catch (InterruptedException exc) { 
					System.out.println(exc); 
				} 
		
				// Release the permit. 
				System.out.println(getName() + " releases the permit.");
				sem.release(); 
		} 
		
		// run by thread B 
		else
		{ 
			System.out.println("Starting " + getName());
			try
			{ 
				// First, get a permit. 
				System.out.println(getName() + " is waiting for a permit.");
			
				// acquiring the lock 
				sem.acquire(); 
			
				System.out.println(getName() + " gets a permit.");
		
				// Now, accessing the shared resource. 
				// other waiting threads will wait, until this 
				// thread release the lock 
				for(int i=0; i < 5; i++) 
				{ 
					sharedObject.count--;
					System.out.println(getName() + ": " + sharedObject.count);
		
					// Now, allowing a context switch -- if possible. 
					// for thread A to execute 
					Thread.sleep(10); 
				} 
			} catch (InterruptedException exc) { 
					System.out.println(exc); 
				} 
				// Release the permit. 
				System.out.println(getName() + " releases the permit.");
				sem.release(); 
		} 
	} 
} 

// Driver class 
public class SemaphoreDemo 
{ 
	public static void main(String args[]) throws InterruptedException 
	{ 
		// creating a Semaphore object 
		// with number of permits 1 
		Semaphore sem = new Semaphore(1);
		SharedObject sharedObject = new SharedObject();
		
		// creating two threads with name A and B 
		// Note that thread A will increment the count 
		// and thread B will decrement the count 
		WorkerThread mt1 = new WorkerThread(sem, sharedObject, "A");
		WorkerThread mt2 = new WorkerThread(sem, sharedObject, "B");
		
		// stating threads A and B 
		mt1.start(); 
		mt2.start(); 
		
		// waiting for threads A and B 
		mt1.join(); 
		mt2.join(); 
		
		// count will always remain 0 after 
		// both threads will complete their execution 
		System.out.println("count: " + sharedObject.count);
	} 
} 


```

L'output dell'esecuzione, può essere:

```
Starting A
Starting B
A is waiting for a permit.
A gets a permit.
B is waiting for a permit.
A: 1
A: 2
A: 3
A: 4
A: 5
A releases the permit.
B gets a permit.
B: 4
B: 3
B: 2
B: 1
B: 0
B releases the permit.
count: 0
```

oppure:

```
Starting B
Starting A
B is waiting for a permit.
A is waiting for a permit.
B gets a permit.
B: -1
B: -2
B: -3
B: -4
B: -5
B releases the permit.
A gets a permit.
A: -4
A: -3
A: -2
A: -1
A: 0
A releases the permit.
count: 0
```

Vedi:

{% embed url="<https://github.com/checksound/EsempiSemafori>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://checksound.gitbook.io/corsojava/i-thread-e-concorrenza/semafori.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
