Mutex e uma abreviacao de exclusao mutua em ingles (mutual exclusion). Seu proposito e evitar que duas ou mais threads acessem simultaneamente o mesmo recurso compartilhado.Para exemplificar um problema de falta de Mutex, imagine um sistema central multi thread responsavel por apoiar o processamento de pedidos de um portal de compras. Neste cenario, o usuario pode clicar duas vezes e submeter duas vezes a requisicao por uma questao de impaciencia, ainda a rede de comunicacao pode conter falha que redunde a requisicao ou a aplicacao servidora pode conter algum bug capaz de emitir mais de uma vez a requisicao para o sistema de processamento final.Se voce for um programador desatento pode nao acreditar na possibilidade de uma requisicao redundante ocasionar impacto financeiro ao usuario e ate mesmo a instituicao responsavel pelo portal sem contar o transtorno para administrar o problema.Para todo efeito, o problema existe e somente um controle transacional delegado a um banco de dados nao resolve porque uma nova transacao em banco de dados so sabe da existencia de uma anterior se esta (anterior) sofrer uma confirmacao ou commit. O controle transacional via banco de dados so surtira efeito se as requisicoes redundantes fossem em sequencia, mas a realidade de requisicoes redundantes e em grande parte paralela.A esta altura a exclusao mutua deve fazer maior sentido caso voce nao a tenha compreendido.O Mutex normalmente e aplicado no servico central (aplicacao) para impedir justamente impactos gerados por falhas em algum sistema intermediario (ex.: web-container) ou sistema terminal (ex.: browser ou usuario).Construindo uma controladora MutexA fim de tornar a Mutex mais eficiente, vamos fazer o uso da colecao com limpeza automatica por tempo de espera chamada WTConcurrentLinkedQueue publicada no artigo Java - Limpeza automatica de colecoes. Essa classe possui dependencia da classe WTTimeObject tambem publicada no mesmo artigo.Agora vamos ao exemplo de uma classe para controle Mutex.import java.io.IOException;public class MutexControl { private static Integer LOCKTIMEOUT_SECS = 120; private static String CARDPREFIX = "_CARD"; private static String TRANSACTIONPREFIX = "_TRANSACTION"; private static MutexControl mutexControl; static { mutexControl = null; } private static synchronized MutexControl getInstance() { if (mutexControl == null) { mutexControl = new MutexControl(); } return mutexControl; } private WTConcurrentHashMap<String, Long> list; private MutexControl() { list = new WTConcurrentHashMap<String, Long>("MutexControl"); } public WTConcurrentHashMap<String, Long> getList() { return list; } private static synchronized void lock(String id, Integer expirationSecs) throws IOException { Long obj = getInstance().getList().get(id); if (obj != null) { if (obj < System.currentTimeMillis()) { getInstance().getList().remove(id); } else { throw new IOException(String.format("A chave de operacao (%s) simultanea esta em uso.", id)); } } Long timeout = System.currentTimeMillis() + (expirationSecs * 1000L); getInstance().getList().put(id, timeout); } private static synchronized void unlock(String id) { getInstance().getList().remove(id); } public static void cardLock(Long cardLogicalNumber) throws IOException { String key = String.format("%s%d", CARDPREFIX, cardLogicalNumber); lock(key, LOCKTIMEOUT_SECS); } public static void cardUnlock(Long cardLogicalNumber) throws IOException { String key = String.format("%s%d", CARDPREFIX, cardLogicalNumber); unlock(key); } public static void transactionLock(Long transactionId) throws IOException { String key = String.format("%s%d", TRANSACTIONPREFIX, transactionId); lock(key, LOCKTIMEOUT_SECS); } public static void transactionUnlock(Long transactionId) throws IOException { String key = String.format("%s%d", TRANSACTIONPREFIX, transactionId); unlock(key); } public static void main(String[]