> For the complete documentation index, see [llms.txt](https://checksound.gitbook.io/corsojava/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://checksound.gitbook.io/corsojava/i-thread-e-concorrenza/semafori.md).

# 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>" %}
