Para entender o ponto dessa postagem, imagine que várias threads estão fazendo um processamento e você vai querer somente o valor mais atual desse processamento ou disparar uma ação depois que todas as threads tenham terminado. Bem, uma forma muito simples é usar join, que vai parar a thread atual até que a thread iniciada tenha concluído a execução.
Claro que no exemplo que vamos mostrar isso não é muito útil, pois as threads estão sendo executados de forma sequencial! Mas o exemplo ser para ilustrar como pode ser utilizado esse método. Com certeza que você ao conhecer esse método, fará uso mais criativo e úteis!
Vamos direto ao ponto, então temos a aplicação abaixo onde diversas threads atualizam o mesmo mapa com o tempo em milis atual e queremos saber o valor mais recente.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.aprendendojavase.concorrencia_no_mapa; | |
import java.util.HashMap; | |
public class AtualizadorMapa { | |
final static HashMap<String, Long> nossoMapa = new HashMap<>(); | |
static final String CHAVE = "CHAVE"; | |
public static void main(String[] args) throws InterruptedException { | |
Runnable atualizaMapa = () -> { | |
long tempoAtual = System.currentTimeMillis(); | |
System.out.println(Thread.currentThread().getName() + " - " + tempoAtual); | |
nossoMapa.put(CHAVE, tempoAtual); | |
}; | |
for (int i = 0; i < 5; i++) { | |
Thread thread = new Thread(atualizaMapa, "Thread " + i); | |
thread.start(); | |
} | |
System.out.println("Último valor do mapa: "+ nossoMapa.get(CHAVE)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.aprendendojavase.concorrencia_no_mapa; | |
import java.util.HashMap; | |
public class AtualizadorMapaSincronizadoComJoin { | |
final static HashMap<String, Long> nossoMapa = new HashMap<>(); | |
static final String CHAVE = "CHAVE"; | |
public static void main(String[] args) throws InterruptedException { | |
Runnable atualizaMapa = () -> { | |
long tempoAtual = System.currentTimeMillis(); | |
System.out.println(Thread.currentThread().getName() + " - " + tempoAtual); | |
nossoMapa.put(CHAVE, tempoAtual); | |
}; | |
for (int i = 0; i < 5; i++) { | |
Thread thread = new Thread(atualizaMapa, "Thread " + i); | |
thread.start(); | |
thread.join(); | |
} | |
System.out.println("Último valor do mapa: "+ nossoMapa.get(CHAVE)); | |
} | |
} |
O código da classe AtualizadorMapa vai dar xabu sim ou com certeza?
Vai sim, terems um resultado como o seguinte:
Thread 1 - 1482988764969
Último valor do mapa: null
Thread 3 - 1482988764969
Thread 2 - 1482988764969
Thread 0 - 1482988764969
Thread 4 - 1482988764969
As vezes vai funcionar. Sim, as vezes as coisas vão sair no lugar, mas nem sempre. Agora imagine a dor de cabeça que implementações concorrentes não dão em produção!
Uma forma simples (inútil, diriam alguns) de resolver é usando o join. Talvez a única vantagem seja, mesmo perdendo a execução paralela, o fato que se uma thread lançar exceção, o problema principal não é afetado e outras threads poderão executar em seguida. Mas lembrem-se, o que temos aqui é um exemplo simples, há muitos possíveis para o join e meu objetivo hoje é somente apresentar esse método. Veja agora o código da classe AtualizadorMapaSincronizadoComJoin e notem que adicionar um join logo após iniciarmos a thread que criamos. Isso garante que a thread principal, a thread da classe, só vai continuar depois que nossa thread terminar o processamento. Como resultado, temos sempre o valor mais atual no mapa após o for...
O nosso objetivo aqui foi somente apresentar esse interessante método. Ah, se você ficou perdido com a forma que declaramos o Runnable ali, veja nosso artigo sobre Java Funcional com Lambdas.
Nenhum comentário:
Postar um comentário