Como implementar Semaforo em Java?

2 respostas
F

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 ?

2 Respostas

V

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.

F

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();
   }
}
Criado 7 de abril de 2012
Ultima resposta 13 de mai. de 2012
Respostas 2
Participantes 2