PROGRAMAÇÃO AVANÇADA Multithreading – Bloqueios Explícitos Um processo com dois estágios (App1) Um processo com dois estágios (App1)
¨ Suponha que cada estágio simplesmente
executa alguma operação (por exemplo, obter alguma “informação” de algum lugar). Por exemplo, , por exemplo, analisar o tempo de um ping ¨ Assuma que essa operação precisa de 1 milissegundo para ser executada (a thread fica bloqueada). Isso dá a chance para outras threads executarem ¨ Um números aleatórios é usado para armazenar a “informação” em uma lista Um processo com dois estágios (App1) Um processo com dois estágios (App1)
¨ Note que o tempo de execução é
sempre maior que 2 segundos ¨ Será que não dá para melhorar esse tempo adicionando múltiplas threads? ¨ Nesse momento, a ideia de multithreading não é a divisão do trabalho, mas a replicação mesmo, ou seja, o trabalho de cada uma será 2 mil, sendo 1 mil para a lista 1 e mais 1 mil para a lista 2 (equivalente a 1 mil pings de envio e 1 mil pings de resposta) Adição de Threads (App2) Condição de corrida (App2)
¨ O problema é o acesso concorrente a
mesma variável compartilhada (list1 e list2) ¨ Precisamos sincronizar o acesso
evitando essa condição de corrida
¨ A estratégia mais simples é usar métodos synchronized Adicionando métodos synchronized (App3) Por que tanto tempo? ¨ O problema do desempenho é que cada objeto tem somente um bloqueio intrínseco ¨ Quando você sincroniza um método você adquire o bloqueio intrínseco do objeto como um todo ¨ Se uma thread executa oneStage, e outra thread quer executar twoStage, esta segunda thread tem que esperar até que a primeira thread libere o bloqueio intrínseco do objeto ¨ Resumo: as threads ficam bloqueadas mesmo que acessem métodos diferentes e que não acessem o mesmo dado (oneStage acessa list1; e twoStage acessa list2) Por que tanto tempo? ¨ O que se deseja é um sistema onde duas (ou mais) threads não acessem o mesmo método ao mesmo tempo (p.ex., duas threads não podem acessar oneStage ao mesmo tempo) ¨ E que uma thread possa executar um método e outra thread possa executar outro método (uma thread acessa oneStage e outra thread acessa twoStage) ¨ A ideia é criar dois bloqueios (locks) separados, um para cada método Locks + blocos synchronized (App4) Locks + blocos synchronized (App4) ¨ O desempenho melhorou em relação ao código anterior (caiu quase pela metade) e também não há condição de corrida ¨ O desempenho tem que ser maior do que 2s mesmo por causa do tempo de execução das operações ¨ As threads não acessam o mesmo “stage” ao mesmo tempo ¨ Note que os locks não foram exatamente nas listas, nem nos métodos, mas em blocos de código Referências ¨ https://docs.oracle.com/javase/tutorial/essential/ concurrency/sync.html Fim