args) { /**************************************************** * Testar bloqueio/desbloqueio de um ficticio cartao por seu id ****************************************************/ Long cardId = 123L; // Teste 1: Bloqueia cartao - Resultado esperado: Deve pemitir try { cardLock(cardId); } catch (IOException e) { System.err.println("Teste 1: " + e.getMessage()); } // Teste 2: Bloqueia cartao - Resultado esperado: Nao deve pemitir try { cardLock(cardId); } catch (IOException e) { System.err.println("Teste 2: " + e.getMessage()); } // Teste 3: Desbloqueia cartao - Resultado esperado: Deve pemitir // Se nao desbloquear ate 120 segundos, desbloqueia automaticamente // Leia a constante LOCKTIMEOUT_SECS try { cardUnlock(cardId); } catch (IOException e) { System.err.println("Teste 3: " + e.getMessage()); } // Teste 4: Bloqueia cartao - Resultado esperado: Deve pemitir try { cardLock(cardId); } catch (IOException e) { System.err.println("Teste 4: " + e.getMessage()); } /**************************************************** * Testar bloqueio/desbloqueio de uma ficticia transacao por seu id ****************************************************/ Long transactionId = 1002L; // Teste 5: Bloqueia transacao - Resultado esperado: Deve pemitir try { transactionLock(transactionId); } catch (IOException e) { System.err.println("Teste 5: " + e.getMessage()); } // Teste 6: Bloqueia transacao - Resultado esperado: Nao deve pemitir try { transactionLock(transactionId); } catch (IOException e) { System.err.println("Teste 6: " + e.getMessage()); } // Teste 7: Desbloqueia transacao - Resultado esperado: Deve pemitir // Se nao desbloquear ate 120 segundos, desbloqueia automaticamente // Leia a constante LOCKTIMEOUT_SECS try { transactionUnlock(transactionId); } catch (IOException e) { System.err.println("Teste 7: " + e.getMessage()); } // Teste 8: Bloqueia transacao - Resultado esperado: Deve pemitir try { transactionLock(transactionId); } catch (IOException e) { System.err.println("Teste 8: " + e.getMessage()); } }}A classe MutexControl contem como principais funcoes lock e unlock para bloquear um recurso pelo seu identificador. Para facilitar o entendimento, na classe ainda foram adicionadas funcoes de bloqueio e desbloqueio mais concretas, sao os casos das funcoes cardLock, cardUnlock, transactionLock e transactionUnlock. Basicamente voce pode criar funcoes de bloqueio e desbloqueio de outros recursos diretos ao utilizar a mesma tecnica de criar as funcoes baseadas num prefixo para o identificador para nao conflitar com controles de outros recursos.Para evitar incidentes serios caso voce se esqueca de desbloquear um recurso apos a operacao ou mesmo que seu controle de excecao deixe o recurso bloqueado por erro, foi determinado um limite de tempo de bloqueio em 120 segundos na constante LOCKTIMEOUT_SECS da classe MutexControl. O parametro pode ser alterado a seu criterio de tolerancia para desbloquear um recurso esquecido no Mutex.Teste da controladora MutexO teste esta na mesma classe controladora no metodo main. Execute a classe em modo de debug preferencialmente e acompanhe os exemplos de controle de operacao de um cartao de id 123 e em seguida, de uma transacao de id 1002.ResultadoNa tentativas de bloqueios redundantes, devem ocorrer as seguintes excecoes:Teste 2: A chave de operacao (_CARD123) simultanea esta em uso.Teste 6: A chave de operacao (_TRANSACTION1002) simultanea esta em uso.ConclusaoAnalogo a um controle de semaforo onde se passa apenas um carro por vez numa via, o Mutex e uma tecnica simples e segura para a exclusao mutua de processamento redundante provocado por falhas de requisicoes redundantes;Ate o proximo artigo.