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. Novo
  2. Executรกvel
  3. Corrida
  4. Esperando
  5. Morto
  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:

  • Linha de cรณdigo 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).
  • Linha de cรณdigo 4: Ele substitui o mรฉtodo run da interface executรกvel, pois รฉ obrigatรณrio substituir esse mรฉtodo
  • Linha de cรณdigo 6: Aqui definimos o mรฉtodo principal no qual iniciaremos a execuรงรฃo do thread.
  • Linha de cรณdigo 7: Aqui estamos criando um novo nome de thread como โ€œguruthread1โ€ instanciando uma nova classe de thread.
  • Linha de cรณdigo 8: usaremos o mรฉtodo โ€œstartโ€ do thread usando a instรขncia โ€œguruthread1โ€. Aqui o thread comeรงarรก a ser executado.
  • Linha de cรณdigo 10: Aqui estamos usando o mรฉtodo โ€œsleepโ€ do thread usando a instรขncia โ€œguruthread1โ€. Conseqรผentemente, o thread ficarรก suspenso por 1000 milissegundos.
  • Cรณdigo 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.
  • Linha de cรณdigo 15: Aqui estamos definindo a prioridade do thread para 1 de qualquer prioridade que fosse
  • Linha de cรณdigo 16: Aqui estamos obtendo a prioridade do thread usando getPriority()
  • Linha de cรณdigo 17: Aqui estamos imprimindo o valor obtido em getPriority
  • Linha de cรณdigo 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:

  • Linha de cรณdigo 3: Pegamos uma classe โ€œGuruThread1โ€ que implementa Runnable (deve ser implementada por qualquer classe cujas instรขncias sejam executadas pelo thread).
  • Linha de cรณdigo 8: Este รฉ o mรฉtodo principal da classe
  • Linha de cรณdigo 9: Aqui estamos instanciando a classe Thread e criando uma instรขncia chamada โ€œguruThread1โ€ e criando um thread.
  • Linha de cรณdigo 10: Aqui estamos instanciando a classe Thread e criando uma instรขncia chamada โ€œguruThread2โ€ e criando um thread.
  • Linha de cรณdigo 11: Estamos iniciando o tรณpico, ou seja, guruThread1.
  • Linha de cรณdigo 12: Estamos iniciando o tรณpico, ou seja, guruThread2.
  • Linha de cรณdigo 13: Produzindo o texto como โ€œOs nomes dos threads sรฃo os seguintes:โ€
  • Linha de cรณdigo 14: Obtendo o nome do thread 1 usando o mรฉtodo getName() da classe thread.
  • Linha de cรณdigo 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:

  • Linha de cรณdigo 2: Aqui estamos pegando uma classe โ€œGuruThread2โ€ que conterรก o mรฉtodo principal.
  • Linha de cรณdigo 4: Aqui estamos pegando um mรฉtodo principal da classe.
  • Linha de cรณdigo 6-7: Aqui estamos criando uma instรขncia da classe GuruThread3 (que รฉ criada nas linhas abaixo do cรณdigo) como โ€œthreadguru1โ€ e estamos iniciando o thread.
  • Linha de cรณdigo 8-9: Aqui estamos criando outra instรขncia da classe GuruThread3 (que รฉ criada nas linhas abaixo do cรณdigo) como โ€œthreadguru2โ€ e estamos iniciando o thread.
  • Linha de cรณdigo 11: Aqui estamos criando uma classe โ€œGuruThread3โ€ que implementa a interface executรกvel (ela deve ser implementada por qualquer classe cujas instรขncias se destinam a ser executadas pelo thread).
  • Linha de cรณdigo 13-14: estamos pegando duas variรกveis โ€‹โ€‹de classe, das quais uma รฉ do tipo classe thread e outra da classe string.
  • Linha de cรณdigo 15-18: estamos substituindo o construtor GuruThread3, que usa um argumento como tipo de string (que รฉ o nome do thread) que รฉ atribuรญdo ร  variรกvel de classe guruname e, portanto, o nome do thread รฉ armazenado.
  • Linha de cรณdigo 20: Aqui estamos substituindo o mรฉtodo run() da interface executรกvel.
  • Linha de cรณdigo 21: Estamos gerando o nome do thread usando a instruรงรฃo println.
  • Linha de cรณdigo 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.
  • Linha de cรณdigo 33: Aqui estamos substituindo o mรฉtodo start da interface executรกvel.
  • Linha de cรณdigo 35: Estamos exibindo o texto โ€œTรณpico iniciadoโ€.
  • Linha de cรณdigo 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,
    • Novo
    • Executรกvel
    • Corrida
    • Esperando
    • Morto
  • 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: