Em Java, a palavra -chave sincronizada e o bloqueio de bloqueio são usadas para realizar o controle simultâneo de acesso dos recursos. Somente threads exclusivos podem entrar na área crítica para acessar recursos (exceto os bloqueios de leitura). O principal objetivo deste subcontrolo é resolver o problema da inconsistência de dados causada por vários threads simultaneamente com o mesmo recurso. Em outro cenário, um recurso possui várias cópias para uso ao mesmo tempo, como várias impressoras na sala da impressora e vários poços para uso ao mesmo tempo. Nesse caso, o Java fornece outro controle de acesso simultâneo - controle simultâneo de acesso para várias cópias do recurso, e o semáforo usado hoje é um deles.
O Java pode detectar possíveis problemas de segurança do encadeamento em nosso sistema da maneira mais rápida através da simulação de código. Aqui, o semáforo (semáforo) e o Countdownlatch (bloqueio) são usados com o ExecorService (pool de threads) para simulação. A principal introdução é a seguinte:
1. Semáforo
Esta aula será fornecida após o JDK 1.5
Semáfore é um semáforo baseado em contagem. Ele pode definir um limite, com base nisso, vários threads competem para obter o sinal de licença e devolvê -lo após fazer seu próprio aplicativo. Depois de exceder o limite, o aplicativo do thread para o sinal de licença será bloqueado. O semáforo pode ser usado para criar alguns pools de objetos, pools de recursos, etc., como pools de conexão de banco de dados. Também podemos criar semáforo com uma contagem de 1, usando -o como um mecanismo semelhante aos bloqueios mutex. Isso também é chamado de semáforo binário, indicando dois estados mutex.
2. Countdownlatch
Esta classe será fornecida após o JDK 1.5.
A classe Countdownlatch pode fazer com que um tópico aguarde outros threads para concluir seu respectivo trabalho antes de executar. Por exemplo, o thread principal do aplicativo deseja executar após o tópico responsável por iniciar o serviço Framework, iniciou todos os serviços da estrutura.
O CountdownLatch é implementado através de um contador e o valor inicial do contador é o número de threads. Sempre que um thread conclui sua própria tarefa, o valor do contador é reduzido em 1. Quando o valor do contador atinge 0, significa que todos os threads concluíram a tarefa e, em seguida, os threads que aguardam na fechadura podem retomar a execução da tarefa.
Como mostrado na figura abaixo:
As duas classes acima podem ser usadas em combinação para alcançar o efeito da simulação de alta simultaneidade. O código a seguir é usado para dar um exemplo:
módulos de pacotes; importar java.util.concurrent.countdownlatch; importar java.util.concurrent.executorService; importar java.util.concurrent.executores; importar java.util.Concurrent.Semaphore; // Número de threads executados simultaneamente ao mesmo tempo em estático público threadtotal = 200; public static int count = 0; public static void main (string [] args) lança Exceção {ExecutorService ExecutSerService = executores.newcachedthreadpool (); // semicondutor, usado para controlar o número de threads simultâneos aqui semáforo final semáforo = novo semáforo (Threadtotal); // bloqueio, que pode realizar o decréscimo do contador de contador CountdownLatch Countdownlatch = new CountdownLatch (ClientTotal); para (int i = 0; i <clientTotal; i ++) {ExecutorService.execute (() -> {tente {// Execute esse método para obter a permissão de execução. semáfore.release (); } contagemDownLatch.await (); // blocos de threads, e o bloco não é liberado até que o valor do bloqueio seja 0. Continue executando o executorService.shutdown (); log.info ("count: {}", count); } private estático void add () {count ++; }}Conforme mostrado no método acima, 5000 solicitações são simuladas e 200 operações simultâneas são de até 200 operações simultâneas ao mesmo tempo. Observe os resultados finais e constate que os resultados são diferentes para cada vez e são inconsistentes com as expectativas. O resultado é o seguinte:
22: 18: 26.449 [Main] Info Modules.CountExample - Contagem: 4997
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [Main] Info Modules.CountExample - Contagem: 4995
22: 18: 26.449 [Main] Info Modules.CountExample - Contagem: 4998
Conclusão final: o método Add não é seguro
Em seguida, como garantir a segurança do thread do método Add, modifique o método ADD da seguinte forma:
private static void add () {count.incremendget ();}Os resultados da execução são os seguintes:
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
22: 18: 26.449 [principal] módulos de informação.CountExample - contagem: 5000
Conclusão Final: O Método Adicionar Modificado Seguro
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.