Multithreading em Java – Tudo o que VOCÊ DEVE Saber

Quando executamos uma aplicação do mundo real, usamos processadores eficientes para uma execução mais rápida. No entanto, apenas a velocidade do processador não pode garantir que sua aplicação seja rápida. Uma das melhores maneiras de criar uma aplicação eficiente em desempenho é utilizar a multithreading.

O que é Multithreading?

A multithreading é um conceito de programação no qual a aplicação pode criar pequenas unidades de tarefas para executar em paralelo. Se você estiver trabalhando em um computador, ele executa várias aplicações e aloca poder de processamento a elas. Um programa simples é executado em sequência, e as instruções do código são executadas uma por uma. Isso é uma aplicação de única thread. No entanto, se a linguagem de programação suportar a criação de várias threads e enviá-las para o sistema operacional executar em paralelo, isso é chamado de multithreading.

Multithreading vs Multiprocessing

Quando falamos sobre multithreading, não importa se a máquina possui um processador de 2 núcleos ou de 16 núcleos. Nosso trabalho é criar uma aplicação com várias threads e permitir que o sistema operacional gerencie a alocação e execução. Em resumo, a multithreading não tem relação com a multiprocessing.

Como o Java suporta multithreading?

O Java tem um ótimo suporte para aplicativos multithreaded. O Java suporta multithreading através da classe Thread. O Thread Java nos permite criar um processo leve que executa algumas tarefas. Podemos criar múltiplos threads em nosso programa e iniciá-los. O tempo de execução do Java cuidará da criação de instruções em nível de máquina e trabalhará com o sistema operacional para executá-las em paralelo.

Quais são os diferentes tipos de threads?

Há dois tipos de threads em um aplicativo – thread de usuário e thread daemon. Quando iniciamos um aplicativo, o principal é o primeiro thread de usuário criado. Podemos criar múltiplos threads de usuário, bem como threads daemon. Quando todos os threads de usuário são executados, a JVM termina o programa.

O que é a prioridade de thread?

Quando criamos uma thread, podemos atribuir sua prioridade. Podemos definir prioridades diferentes para threads diferentes, mas isso não garante que uma thread com prioridade mais alta será executada antes de uma thread com prioridade mais baixa. O escalonador de threads é parte da implementação do sistema operacional e, quando uma thread é iniciada, sua execução é controlada pelo escalonador de threads, e a JVM não tem controle sobre sua execução.

Como Criar uma Thread em Java?

Podemos criar threads tanto implementando a interface Runnable quanto estendendo a classe Thread.

Thread t = new Thread(new Runnable(){
    @Override
    public void run() {
    }
});

Above é uma declaração em uma linha para criar uma nova thread. Aqui estamos criando um Runnable como uma classe anônima. Se você estiver familiarizado com expressões lambda, podemos criar uma thread com um código muito mais curto.

Runnable runnable = () -> System.out.println("Hello");

Depois de criar uma thread, precisamos iniciar sua execução chamando o método start().

runnable.start();

I have written a lot of posts explaining the concepts of multithreading in Java. You can go through these in sequence to learn everything about multithreading, its real-life usage, thread lifecycle, thread pool, etc.

1. Java Thread e Runnable

Essa é a primeira postagem sobre a classe Thread e a interface Runnable. Você também aprenderá sobre Processo e Thread. Qual é a diferença entre Thread e Processo? Benefícios do uso de Threads e como podemos criar Threads usando a interface Runnable e a classe Thread. Esta postagem também compara a interface Runnable com a classe Thread.

2. Java Thread Sleep

O `Java Thread sleep` é usado para pausar a execução da thread atual. Vamos usar o Thread sleep extensivamente em postagens futuras, então é bom saber como funciona e se é preciso ou não?

3. Java Thread Join

Às vezes, precisamos aguardar que outras threads concluam sua execução antes de prosseguirmos. Podemos alcançar isso usando o método `Thread join`, aprenda como funciona e quando devemos usá-lo.

4. Estados das Threads em Java

Compreender os diferentes estados da thread é importante. Saiba como uma thread muda de estado e como o escalonador de threads do sistema operacional altera o estado de uma thread.

5. Java Thread wait, notify e notifyAll

A classe Object do Java contém três métodos para comunicar o estado de bloqueio de um recurso. Aprenda com exemplos o uso desses métodos da classe Object em uma implementação simples de Wait-Notify.

6. Segurança de Threads e Sincronização

Sabemos que Threads compartilham recursos de objetos, o que pode levar à corrupção de dados, pois essas operações não são atômicas. Aprenda como podemos alcançar a segurança de threads em Java usando diferentes métodos. Leia este post para entender o uso correto de sincronização, métodos sincronizados e blocos sincronizados.

7. Exceção Java na thread principal

A JVM cria a primeira thread usando o método main. Este post explica algumas exceções comuns que encontramos no dia a dia, suas causas e como corrigi-las.

8. Thread Safety in Singleton Class

Neste artigo, você aprenderá os conceitos básicos de criação de uma classe Singleton. Quais são os problemas de segurança de thread com diferentes implementações? Como podemos alcançar a segurança de thread em uma classe Singleton.

9. Daemon Thread in Java

A simple article explaining daemon threads and how we can create daemon threads in java.

10. Java Thread Local

Brazilian Portuguese Translation:
Nós sabemos que as threads compartilham as variáveis do objeto, mas e se quisermos ter variáveis locais à thread criadas no nível da classe? O Java fornece a classe utilitária ThreadLocal para criar variáveis locais à thread. Leia mais para aprender como podemos criar variáveis ThreadLocal no programa Java.

11. Despejo de Thread Java

O despejo de thread Java fornece informações sobre a thread atual. Um despejo de thread é útil para analisar problemas de desempenho com o aplicativo. Você pode usaro despejo de thread para encontrar e corrigir situações de deadlock. Este post explica diferentes métodos que podem ser usados para gerar despejos de thread em Java.

12. Como Analisar Deadlock em Java

Deadlock é uma situação em que múltiplas threads estão esperando umas pelas outras para liberar recursos, causando uma dependência cíclica. Este artigo discute a situação na qual podemos obter um deadlock em um programa Java. Como podemos usar o Thread dump para encontrar o deadlock e as melhores práticas para evitar o deadlock em um programa Java.

13. Thread do Timer do Java

Este post explica como podemos usar as classes Timer e TimerTask do Java para criar tarefas para serem executadas em intervalos programados, um exemplo de programa mostrando seu uso e como podemos cancelar o timer.

14. Problema do Produtor-Consumidor em Java

Antes do Java 5, o problema do produtor-consumidor podia ser resolvido usando os métodos wait() e notify(), mas a introdução de BlockingQueue tornou isso muito fácil. Aprenda como podemos usar BlockingQueue para resolver o problema do produtor-consumidor em Java.

15. Java Thread Pool

O Java Thread Pool é uma coleção de threads trabalhadoras aguardando para processar tarefas. A introdução do framework Executor no Java 5 tornou muito fácil criar um pool de threads em Java. Podemos usar as classes Executors e ThreadPoolExecutor para criar e gerenciar um pool de threads.

16. Java Callable Future

Às vezes, queremos que nossa Thread retorne alguns valores que podemos usar. O Callable do Java 5 pode ser usado nesse caso, o que é semelhante à interface Runnable. Podemos usar o framework Executor para executar tarefas Callable.

17. Exemplo de Java FutureTask

A classe FutureTask é a classe concreta base que implementa a interface Future. Nós a usamos com a implementação Callable e Executors para processamento assíncrono. A classe FutureTask fornece métodos de implementação para verificar o estado da tarefa e retornar o valor para o programa chamador assim que seu processamento estiver concluído. É útil quando você deseja substituir alguns dos métodos de implementação da interface Future.

Conclusão

A programação multithreading é um tópico muito amplo e escrever tudo sobre isso em um único post não seria possível. Se você passar pelos posts acima em sequência, aprenderá tudo sobre multithreading em Java.

Source:
https://www.digitalocean.com/community/tutorials/multithreading-in-java