Existe um objeto Mutex em java ou uma maneira de criar um? Estou perguntando porque um objeto Semaphore inicializado com 1 licença não me ajuda. Pense neste caso:
try {
semaphore.acquire();
//do stuff
semaphore.release();
} catch (Exception e) {
semaphore.release();
}
se ocorrer uma exceção na primeira aquisição, a liberação no bloco catch aumentará as permissões e o semáforo não será mais um semáforo binário.
Será a maneira correta?
try {
semaphore.acquire();
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
O código acima garantirá que o semáforo será binário?
Respostas:
Veja esta página: http://www.oracle.com/technetwork/articles/javase/index-140767.html
Tem um padrão ligeiramente diferente que é (eu acho) o que você está procurando:
Nesse uso, você só está ligando
release()
depois de umacquire()
fonte
Qualquer objeto em Java pode ser usado como um bloqueio usando um
synchronized
bloco. Isso também irá automaticamente liberar o bloqueio quando ocorrer uma exceção.Você pode ler mais sobre isso aqui: Bloqueios intrínsecos e sincronização
fonte
synchronized
, você verá o que é mais legível e menos sujeito a erros.transaction.begin(); transaction.commit()
).someObject.wait(timeout)
esomeObject.notify()
enquanto analisa o código desta resposta.fonte
"Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements."
de: docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/… ... embora você tenha razão . A resposta de Argv não ilustra nem explica essas operações.private final ReentrantLock _mutex = ...
, pode usar getHoldCount () para retornar o número de bloqueios de thread. (Você pode aplicar umCondition
para evitar isso. Consulte a API .)Ninguém mencionou isso claramente, mas esse tipo de padrão geralmente não é adequado para semáforos. O motivo é que qualquer thread pode liberar um semáforo, mas normalmente você só deseja que o thread do proprietário que foi bloqueado originalmente seja desbloqueado . Para este caso de uso, em Java, geralmente usamos ReentrantLocks, que pode ser criado assim:
E o padrão de design usual de uso é:
Aqui está um exemplo no código-fonte java onde você pode ver esse padrão em ação.
Os bloqueios reentrantes têm o benefício adicional de apoiar a justiça.
Use semáforos apenas se precisar de uma semântica de liberação sem propriedade.
fonte
count=1
não é um bloqueio de exclusão mútua.lock
por exemplo, éReentrantLock
ummutex
? Não sei por quemutex
ebinary semaphore
estão sendo considerados a mesma entidade.Semaphore
pode ser liberado por qualquer thread, de modo que pode não garantir proteçãocritical section
. Alguma ideia?Eu acho que você deveria tentar com:
Durante a inicialização do Semaphore:
E no seu
Runnable Implementation
fonte
O erro na postagem original é a chamada purchase () definida dentro do loop try. Aqui está uma abordagem correta para usar semáforo "binário" (Mutex):
fonte
Para garantir que a
Semaphore
seja binário, você só precisa passar o número de licenças como 1 ao criar o semáforo. Os Javadocs têm um pouco mais de explicação.fonte
O bloqueio de cada objeto é um pouco diferente do design Mutex / Semaphore. Por exemplo, não há maneira de implementar corretamente o cruzamento de nós vinculados com a liberação do bloqueio do nó anterior e a captura do próximo. Mas com mutex é fácil de implementar:
Atualmente, não existe essa classe em
java.util.concurrent
, mas você pode encontrar a implementação de Mutext aqui Mutex.java . Quanto às bibliotecas padrão, o Semaphore fornece todas essas funcionalidades e muito mais.fonte