Como implementar Semaforo em Java?

Nao estou conseguindo implementar um semáforo (sem usar a classe semaphore ) em java :cry:
Ja procurei pra caramba no Google e ainda não tive uma ideia de como fazer .

O professor disse que nao valia usar “sincronização dos monitores” (Sei nem o que é isso :? ) e nem usar aqueles algoritmos em que um laço infinito fica prendendo as Threads e consumindo processamento sem necessidade.

A unica coisa que consegui pensar ate agora é que vou ter que fazer uma lista do tipo fila (circular) e que vou fazer todas as Threads que derem start pararem e adicionalas nessa lista e executar a primeira a ser adicionada, depois que a primeira sair da seçao critica vou para-la e executar a segunda e assim por diante. O problema ta nesse parar e continuar que eu nao se fazer :frowning: Os metodos da classe Thread sao deprecated.

Alguem pode oferecer alguma luz ?

1 curtida

Um mínimo de sincronização você vai ter que usar, ou não será capaz de usar o wait() e o notifyAll().

Em todo caso, vale a pena ler como se faz em C, num livro de sistemas operacionais. Você precisará a trabalhar com uma região crítica, e provavelmente terá que criar sua própria classe de semáforo para fazer o controle.

PS: Threads e sincronização jamais é um assunto “básico”. Vou mover seu tópico para Java Avançado.

Nao sei se estou indo contra regras do fórum por postar um programa completo.
Mas como esse exercício dá um certo trabalho e é puramente acadêmico …

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class BinarySemaphore {
   AtomicInteger value;
   ConcurrentLinkedQueue queue;
   

   public BinarySemaphore () {
      value = new AtomicInteger(1);
      queue = new ConcurrentLinkedQueue();
   }

   public void P() {
      if (! value.compareAndSet(1,0)) block();
   }

   public void V() {
      if (! queue.isEmpty()) unblock();
      else value.set(1);
   }

   private void block() {
      Thread t = Thread.currentThread();
      queue.add(t);
      t.suspend();
   }

   private void unblock() {
      Thread t = (Thread) queue.poll();
      if (t != null) t.resume();
   }
}