Ordenar Servidor Contador
O exemplo acima é uma ordenado servidor contador que queremos construir. Quando você clicar no botão:
- Uma solicitação assíncrona é enviada para um servidor
- O servidor incrementa um contador interno
- O servidor retorna o valor atual do contador
- O cliente (nossa página) exibe o contador em um sistema mostrada acima.
é importante que a ordem dos números seja preservada quando recebida. Então, como podemos sincronizar a ordem das solicitações? Sabemos que as solicitações de rede são assíncronas. É totalmente possível que o primeiro pedido demore mais para chegar do que o segundo pedido, ou o segundo pedido demore mais do que o terceiro pedido, e assim por diante. Esta chegada fora de ordem de pedidos será um problema para a nossa aplicação.
a abordagem ‘sem sincronização’
o que aconteceria se desenvolvêssemos este aplicativo sem construções de sincronização? Aqui está uma implementação de amostra de uma simulação deste aplicativo sem sincronização.
o servidor é simulado com processCommmand()
e os atrasos na rede são simulados com serverDelay()
. Como não há mecanismos de sincronização, uma vez que o botão “clique em mim” é clicado, uma nova solicitação é disparada imediatamente.
este é o resultado desta implementação.
Uh oh — os números, como esperado, estão aparecendo fora de ordem, e não conseguimos fazer o nosso aplicativo para mostrar números em ordem.
superando o problema fora de ordem com Mutex
o problema é que as solicitações de rede estão fora de ordem, mas nosso aplicativo quer que elas estejam em ordem. Uma maneira de resolver isso é usar um bloqueio Mutex para permitir que apenas uma solicitação seja processada por vez, bloqueando as outras solicitações até que seja a vez delas.
aqui está a implementação com Mutex.
o fluxo de uso da API Mutex é o seguinte:
- linha 23: uma solicitação para adquirir o
clientLock
é iniciada. Esta solicitação bloqueará se outra pessoa já adquiriu o bloqueio e ainda não o lançou - linha 33: o bloqueio do cliente é liberado depois que o servidor respondeu e mostramos o brinde. Isso permite que outros eventos de clique de botão agora compitam pelo bloqueio e iniciem sua solicitação de rede do servidor!
este mecanismo de bloqueio garante que apenas um evento de botão será processado de cada vez, bloqueando e enfileirando os outros. Agora alcançamos a implementação ordenada pretendida do nosso exemplo original mostrado no início!
número limite de brindes visíveis
e se você não gostar que vários brindes possam inundar a tela de cada vez? Podemos estender nossa lógica para limitar o número de brindes exibidos de cada vez. Nossa construção de sincronização aqui seria um semáforo!
pense em um Sempahore como um Mutex, mas pode permitir que várias solicitações assíncronas executem um pedaço de código por vez. Você também pode configurar o número máximo!
usando um Mutex e semáforo, consegui limitar o número de brindes na tela para 2 de cada vez.
E aqui está o código associado com o exemplo acima
Linha 6
O Sempahore estrutura é inicializada com o valor de 2, qual especifica que apenas um, no máximo, 2 torradas podem ser exibidas de uma vez.
linha 26-31
nossa lógica de semáforo vem nos ajudar quando queremos exibir o brinde. Tentamos adquirir o Sempahore. Se formos bem-sucedidos, criamos o objeto Toast e passamos releaseSemaphore()
para a função completeCallback
do Toast. Este retorno de chamada é chamado quando o brinde é demitido.