Multithreading em Java


Qualquer aplicativo pode ter vรกrios processos (instรขncias). Cada um desses processos pode ser atribuรญdo como um รบnico thread ou como vรกrios threads. Veremos neste tutorial como realizar mรบltiplas tarefas ao mesmo tempo e tambรฉm aprenderemos mais sobre threads e sincronizaรงรฃo entre threads.

O que รฉ thread รบnico?

Um รบnico tรณpico em Java รฉ basicamente uma unidade de processamento leve e menor. Java usa threads usando uma โ€œThread Classโ€. Existem dois tipos de thread โ€“ thread de usuรกrio e thread daemon (os threads daemon sรฃo usados โ€‹โ€‹quando queremos limpar o aplicativo e sรฃo usados โ€‹โ€‹em segundo plano). Quando um aplicativo รฉ iniciado pela primeira vez, o thread do usuรกrio รฉ criado. Depois disso, podemos criar muitos threads do usuรกrio e threads daemon.

Exemplo de thread รบnico:

package demotest;

public class GuruThread
{
       public static void main(String[] args) {
              System.out.println("Single Thread");
       }
}

Vantagens do thread รบnico:

  • Reduz a sobrecarga no aplicativo ร  medida que um รบnico thread รฉ executado no sistema
  • Alรฉm disso, reduz o custo de manutenรงรฃo do aplicativo.

O que รฉ multithreading Java?

multithreading in Java รฉ um processo de execuรงรฃo de dois ou mais threads simultaneamente para utilizaรงรฃo mรกxima da CPU. Os aplicativos multithread executam dois ou mais threads simultaneamente. Portanto, tambรฉm รฉ conhecido como Concorrรชncia em Java. Cada thread corre paralelamente um ao outro. Vรกrios threads nรฃo alocam รกreas de memรณria separadas, portanto, economizam memรณria. Alรฉm disso, a alternรขncia de contexto entre threads leva menos tempo.

Exemplo de multithread:

package demotest;
public class GuruThread1 implements Runnable
{
       public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

Vantagens do multithread:

  • Os usuรกrios nรฃo sรฃo bloqueados porque os threads sรฃo independentes e ร s vezes podemos realizar vรกrias operaรงรตes
  • Como tal, os threads sรฃo independentes, os outros threads nรฃo serรฃo afetados se um thread atender a uma exceรงรฃo.

Ciclo de vida do thread em Java

O ciclo de vida de um thread:

Ciclo de vida do thread em Java
Ciclo de vida do thread em Java

Existem vรกrios estรกgios do ciclo de vida do thread, conforme mostrado no diagrama acima:

  1. New
  2. Executรกvel
  3. Corrida
  4. Esperando
  5. Dead
  1. Novo: Nesta fase, o thread รฉ criado utilizando a classe โ€œThread classโ€. Ele permanece neste estado atรฉ o programa comeรงa o segmento. Tambรฉm รฉ conhecido como fio nascido.
  2. Executรกvel: Nesta pรกgina, a instรขncia do thread รฉ invocada com um mรฉtodo start. O controle do thread รฉ dado ao agendador para finalizar a execuรงรฃo. Depende do agendador se o thread deve ser executado.
  3. Corrida: Quando o thread comeรงa a ser executado, o estado รฉ alterado para o estado โ€œem execuรงรฃoโ€. O agendador seleciona um thread do pool de threads e comeรงa a ser executado no aplicativo.
  4. Esperando: Este รฉ o estado em que um thread deve esperar. Como hรก vรกrios threads em execuรงรฃo no aplicativo, hรก necessidade de sincronizaรงรฃo entre os threads. Portanto, um thread tem que esperar atรฉ que o outro thread seja executado. Portanto, este estado รฉ referido como estado de espera.
  5. Morto: Este รฉ o estado quando o thread รฉ encerrado. O thread estรก em estado de execuรงรฃo e assim que conclui o processamento ele estรก em โ€œestado mortoโ€.


Mรฉtodos de Multithreading em Java

Alguns dos mรฉtodos comumente usados โ€‹โ€‹para threads sรฃo:

Forma Descriรงรฃo
comeรงar() Este mรฉtodo inicia a execuรงรฃo do thread e JVM chama o mรฉtodo run() no thread.
Dormir (int milissegundos) Este mรฉtodo faz o thread dormir, portanto a execuรงรฃo do thread serรก pausada por milissegundos fornecidos e depois disso, o thread comeรงarรก a ser executado novamente. Isso ajuda na sincronizaรงรฃo dos threads.
getName () Ele retorna o nome do thread.
setPriority(int novaprioridade) Isso altera a prioridade do thread.
colheita () Isso faz com que o thread atual seja interrompido e outros threads sejam executados.

Exemplo: Neste programa multithreading em Java Por exemplo, vamos criar um thread e explorar mรฉtodos integrados disponรญveis para threads.

package demotest;
public class thread_example1 implements Runnable {
    @Override
    public void run() {
    }
    public static void main(String[] args) {
        Thread guruthread1 = new Thread();
        guruthread1.start();
        try {
            guruthread1.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        guruthread1.setPriority(1);
        int gurupriority = guruthread1.getPriority();
        System.out.println(gurupriority);
        System.out.println("Thread Running");
  }
}

Explicaรงรฃo do cรณdigo:

  • Code Linha 2: Estamos criando uma classe โ€œthread_Example1โ€ que implementa a interface Runnable (ela deve ser implementada por qualquer classe cujas instรขncias sejam executadas pelo thread).
  • Code Linha 4: Ele substitui o mรฉtodo run da interface executรกvel, pois รฉ obrigatรณrio substituir esse mรฉtodo
  • Code Linha 6: Aqui definimos o mรฉtodo principal no qual iniciaremos a execuรงรฃo do thread.
  • Code Linha 7: Aqui estamos criando um novo nome de thread como โ€œguruthread1โ€ instanciando uma nova classe de thread.
  • Code Linha 8: usaremos o mรฉtodo โ€œstartโ€ do thread usando a instรขncia โ€œguruthread1โ€. Aqui o thread comeรงarรก a ser executado.
  • Code Linha 10: Aqui estamos usando o mรฉtodo โ€œsleepโ€ do thread usando a instรขncia โ€œguruthread1โ€. Conseqรผentemente, o thread ficarรก suspenso por 1000 milissegundos.
  • Code 9-14: Aqui colocamos o mรฉtodo sleep no bloco try catch, pois hรก uma exceรงรฃo verificada que ocorre, ou seja, exceรงรฃo interrompida.
  • Code Linha 15: Aqui estamos definindo a prioridade do thread para 1 de qualquer prioridade que fosse
  • Code Linha 16: Aqui estamos obtendo a prioridade do thread usando getPriority()
  • Code Linha 17: Aqui estamos imprimindo o valor obtido em getPriority
  • Code Linha 18: Aqui estamos escrevendo um texto que o tรณpico estรก rodando.

Ao executar o cรณdigo acima, vocรช obtรฉm a seguinte saรญda:

Exemplo de tรณpico em Java

Saรญda:

5 รฉ a prioridade do Thread e Thread Running รฉ o texto que รฉ a saรญda do nosso cรณdigo.

Java Fio Synchronizaรงรฃo

Em multithreading, hรก o comportamento assรญncrono dos programas. Se um thread estiver gravando alguns dados e outro thread estiver lendo dados ao mesmo tempo, pode criar inconsistรชncia no aplicativo. Quando hรก necessidade de acessar os recursos compartilhados por dois ou mais threads, entรฃo a abordagem de sincronizaรงรฃo รฉ utilizada. Java forneceu mรฉtodos sincronizados para implementar comportamento sincronizado.

Nessa abordagem, uma vez que o thread alcanรงa o bloco synchronized, entรฃo nenhum outro thread pode chamar esse mรฉtodo no mesmo objeto. Todos os threads tรชm que esperar atรฉ que o thread termine o bloco synchronized e saia dele. Dessa forma, a sincronizaรงรฃo ajuda em um aplicativo multithread. Um thread tem que esperar atรฉ que outro thread termine sua execuรงรฃo, somente entรฃo os outros threads sรฃo permitidos para execuรงรฃo.

Pode ser escrito da seguinte forma:

Synchronized(object)
{  
        //Block of statements to be synchronized
}

Multithreading em Java Programas de exemplo

Neste multithreading Java Por exemplo, pegaremos dois threads e buscaremos os nomes dos threads.

Exemplo1:

GuruThread1.java
package demotest;
public class GuruThread1 implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

Explicaรงรฃo do cรณdigo:

  • Code Linha 3: Fizemos um curso โ€œGuruThread1โ€, que implementa Runnable (deve ser implementada por qualquer classe cujas instรขncias se destinam a ser executadas pela thread).
  • Code Linha 8: Este รฉ o mรฉtodo principal da classe
  • Code Linha 9: Aqui estamos instanciando a classe Thread e criando uma instรขncia chamada โ€œguruThread1โ€ e criando um thread.
  • Code Linha 10: Aqui estamos instanciando a classe Thread e criando uma instรขncia chamada โ€œguruThread2โ€ e criando um thread.
  • Code Linha 11: Estamos iniciando o tรณpico, ou seja, guruThread1.
  • Code Linha 12: Estamos iniciando o tรณpico, ou seja, guruThread2.
  • Code Linha 13: Produzindo o texto como โ€œOs nomes dos threads sรฃo os seguintes:โ€
  • Code Linha 14: Obtendo o nome do thread 1 usando o mรฉtodo getName() da classe thread.
  • Code Linha 15: Obtendo o nome do thread 2 usando o mรฉtodo getName() da classe thread.

Ao executar o cรณdigo acima, vocรช obtรฉm a seguinte saรญda:

Java Exemplo de multithreading

Saรญda:

Os nomes dos threads estรฃo sendo exibidos aqui como

  • Guru1
  • Guru2

2 exemplo:

Neste multithreading em Java Por exemplo, aprenderemos sobre como substituir os mรฉtodos run() e start() de uma interface executรกvel e criar dois threads dessa classe e executรก-los de acordo.

Alรฉm disso, estamos tendo duas aulas,

  • Um que implementarรก a interface executรกvel e
  • Outro que terรก o mรฉtodo principal e serรก executado de acordo.
package demotest;
public class GuruThread2 {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GuruThread3 threadguru1 = new GuruThread3("guru1");
  threadguru1.start();
  GuruThread3 threadguru2 = new GuruThread3("guru2");
  threadguru2.start();
 }
}
class GuruThread3 implements Runnable {
 Thread guruthread;
 private String guruname;
 GuruThread3(String name) {
  guruname = name;
 }
 @Override
 public void run() {
  System.out.println("Thread running" + guruname);
  for (int i = 0; i < 4; i++) {
   System.out.println(i);
   System.out.println(guruname);
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    System.out.println("Thread has been interrupted");
   }
  }
 }
 public void start() {
  System.out.println("Thread started");
  if (guruthread == null) {
   guruthread = new Thread(this, guruname);
   guruthread.start();
  }
 }
}

Explicaรงรฃo do cรณdigo:

  • Code Linha 2: Aqui estamos tendo uma aula โ€œGuruThread2โ€, que conterรก o mรฉtodo principal.
  • Code Linha 4: Aqui estamos pegando um mรฉtodo principal da classe.
  • Code Linha 6-7: Aqui estamos criando uma instรขncia da classe. GuruA Thread3 (criada nas linhas de cรณdigo abaixo) รฉ denominada โ€œthreadguru1โ€ e estamos iniciando a thread.
  • Code Linha 8-9: Aqui estamos criando outra instรขncia da classe. GuruA Thread3 (criada nas linhas de cรณdigo abaixo) รฉ denominada โ€œthreadguru2โ€ e estamos iniciando a thread.
  • Code Linha 11: Aqui estamos criando uma classe โ€œGuruThread3โ€, que implementa a interface Runnable (ela deve ser implementada por qualquer classe cujas instรขncias se destinam a ser executadas pela thread).
  • Code Linha 13-14: estamos pegando duas variรกveis โ€‹โ€‹de classe, das quais uma รฉ do tipo classe thread e outra da classe string.
  • Code Linha 15-18: estamos anulando o GuruO construtor Thread3 recebe um argumento do tipo string (que รฉ o nome da thread) e o atribui ร  variรกvel de classe guruname, armazenando assim o nome da thread.
  • Code Linha 20: Aqui estamos substituindo o mรฉtodo run() da interface executรกvel.
  • Code Linha 21: Estamos gerando o nome do thread usando a instruรงรฃo println.
  • Code Linha 22-31: Aqui estamos usando um loop for com contador inicializado em 0, e nรฃo deve ser menor que 4 (podemos pegar qualquer nรบmero, portanto aqui o loop serรก executado 4 vezes) e incrementando o contador. Estamos imprimindo o nome do thread e tambรฉm fazendo com que o thread fique suspenso por 1000 milissegundos dentro de um bloco try-catch, pois o mรฉtodo sleep gerou uma exceรงรฃo verificada.
  • Code Linha 33: Aqui estamos substituindo o mรฉtodo start da interface executรกvel.
  • Code Linha 35: Estamos exibindo o texto โ€œTรณpico iniciadoโ€.
  • Code Linha 36-40: Aqui estamos adotando uma condiรงรฃo if para verificar se a variรกvel de classe guruthread tem valor ou nรฃo. Se for nulo, entรฃo estamos criando uma instรขncia usando a classe thread que leva o nome como parรขmetro (valor para o qual foi atribuรญdo no construtor). Depois disso, o thread รฉ iniciado usando o mรฉtodo start().

Ao executar o cรณdigo acima vocรช obtรฉm a seguinte saรญda:

Exemplo de multithreading em Java

saรญda:

Existem dois threads, portanto, recebemos duas vezes a mensagem โ€œTรณpico iniciadoโ€.

Obtemos os nomes dos threads conforme os geramos.

Ele entra no loop for onde imprimimos o contador e o nome do thread e o contador comeรงa com 0.

O loop รฉ executado trรชs vezes e entre o thread fica inativo por 1000 milissegundos.

Portanto, primeiro obtemos guru1, depois guru2 e novamente guru2 porque o thread dorme aqui por 1000 milissegundos e depois o prรณximo guru1 e novamente guru1, o thread dorme por 1000 milissegundos, entรฃo obtemos guru2 e depois guru1.

Resumo

Neste tutorial, vimos aplicativos multithread em Java e como usar thread รบnico e multi thread em Java.

  • Explique multithreading em Java: no multithreading, os usuรกrios nรฃo sรฃo bloqueados, pois os threads sรฃo independentes e podem executar vรกrias operaรงรตes ao mesmo tempo
  • Vรกrios estรกgios do ciclo de vida do fio sรฃo,
    • New
    • Executรกvel
    • Corrida
    • Esperando
    • Dead
  • Tambรฉm aprendemos sobre Sincronizaรงรฃo entre threads, o que ajuda o aplicativo a funcionar sem problemas.
  • Programaรงรฃo multithread em Java facilita muito mais tarefas de aplicaรงรฃo.

Resuma esta postagem com: