Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> Java

Java - Multithreading


Java é uma linguagem de programação multithread o que significa que podemos desenvolver programas multi-thread usando Java. Um programa multithread contém duas ou mais partes que podem ser executadas simultaneamente e cada parte pode lidar com uma tarefa diferente ao mesmo tempo, otimizando o uso dos recursos disponíveis, especialmente quando o computador possui várias CPUs.

Por definição, multitarefa é quando vários processos compartilham recursos de processamento comuns, como uma CPU. Multi-threading estende a ideia de multitarefa em aplicativos onde você pode subdividir operações específicas dentro de um único aplicativo em threads individuais. Cada um dos threads pode ser executado em paralelo. O sistema operacional divide o tempo de processamento não apenas entre diferentes aplicativos, mas também entre cada thread dentro de um aplicativo.

O multithreading permite que você escreva de uma maneira em que várias atividades possam prosseguir simultaneamente no mesmo programa.

Ciclo de vida de um thread


Uma thread passa por vários estágios em seu ciclo de vida. Por exemplo, um thread nasce, é iniciado, é executado e depois morre. O diagrama a seguir mostra o ciclo de vida completo de um encadeamento.

A seguir estão os estágios do ciclo de vida -

Prioridades do segmento


Cada thread Java tem uma prioridade que ajuda o sistema operacional a determinar a ordem na qual os threads são agendados.

As prioridades do encadeamento Java estão no intervalo entre MIN_PRIORITY (uma constante de 1) e MAX_PRIORITY (uma constante de 10). Por padrão, cada thread recebe prioridade NORM_PRIORITY (uma constante de 5).

Threads com prioridade mais alta são mais importantes para um programa e devem ter tempo de processador alocado antes de threads de prioridade mais baixa. No entanto, as prioridades de thread não podem garantir a ordem na qual os threads são executados e são muito dependentes da plataforma.

Criar um thread implementando uma interface executável


Se sua classe pretende ser executada como um thread, você pode conseguir isso implementando um Runnable interface. Você precisará seguir três etapas básicas -

Etapa 1


Como primeiro passo, você precisa implementar um método run() fornecido por um Runnable interface. Esse método fornece um ponto de entrada para o encadeamento e você colocará sua lógica de negócios completa dentro desse método. A seguir está uma sintaxe simples do método run() −
public void run( )

Etapa 2


Como segundo passo, você instanciará um Thread objeto usando o seguinte construtor -
Thread(Runnable threadObj, String threadName);

Onde, threadObj é uma instância de uma classe que implementa o Runnable interface e threadName é o nome dado ao novo tópico.

Etapa 3


Uma vez que um objeto Thread é criado, você pode iniciá-lo chamando start() método, que executa uma chamada ao método run( ). A seguir está uma sintaxe simples do método start() −
void start();

Exemplo


Aqui está um exemplo que cria um novo thread e começa a executá-lo -
Demonstração ao vivo
class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;
   
   RunnableDemo( String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      RunnableDemo R1 = new RunnableDemo( "Thread-1");
      R1.start();
      
      RunnableDemo R2 = new RunnableDemo( "Thread-2");
      R2.start();
   }   
}

Isso produzirá o seguinte resultado -

Saída

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Criar um thread estendendo uma classe de thread


A segunda maneira de criar um thread é criar uma nova classe que estenda Thread classe usando as duas etapas simples a seguir. Essa abordagem fornece mais flexibilidade na manipulação de vários threads criados usando métodos disponíveis na classe Thread.

Etapa 1


Você precisará substituir run( ) método disponível na classe Thread. Esse método fornece um ponto de entrada para o encadeamento e você colocará sua lógica de negócios completa dentro desse método. A seguir está uma sintaxe simples do método run() −
public void run( )

Etapa 2


Uma vez que o objeto Thread é criado, você pode iniciá-lo chamando start() método, que executa uma chamada ao método run( ). A seguir está uma sintaxe simples do método start() −
void start( );

Exemplo


Aqui está o programa anterior reescrito para estender o Thread -
Demonstração ao vivo
class ThreadDemo extends Thread {
   private Thread t;
   private String threadName;
   
   ThreadDemo( String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      ThreadDemo T1 = new ThreadDemo( "Thread-1");
      T1.start();
      
      ThreadDemo T2 = new ThreadDemo( "Thread-2");
      T2.start();
   }   
}

Isso produzirá o seguinte resultado -

Saída

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Métodos de thread


A seguir está a lista de métodos importantes disponíveis na classe Thread.
Nº Sr. Método e descrição
1
início nulo público()

Inicia o thread em um caminho de execução separado e, em seguida, invoca o método run() neste objeto Thread.
2
execução nula pública()

Se esse objeto Thread foi instanciado usando um destino Runnable separado, o método run() será invocado nesse objeto Runnable.
3
public final void setName(String name)

Altera o nome do objeto Thread. Há também um método getName() para recuperar o nome.
4
public final void setPriority(int priority)

Define a prioridade deste objeto Thread. Os valores possíveis estão entre 1 e 10.
5
public final void setDaemon(boolean on)

Um parâmetro true denota este Thread como um thread daemon.
6
junção nula final pública (longo milissegundos)

O thread atual invoca esse método em um segundo thread, fazendo com que o thread atual bloqueie até que o segundo thread termine ou o número especificado de milissegundos passe.
7
interrupção void pública()

Interrompe este encadeamento, fazendo com que ele continue a execução se tiver sido bloqueado por qualquer motivo.
8
public final booleano isAlive()

Retorna true se o encadeamento estiver ativo, ou seja, a qualquer momento após o início do encadeamento, mas antes de ser executado até a conclusão.

Os métodos anteriores são invocados em um objeto Thread específico. Os métodos a seguir na classe Thread são estáticos. Invocar um dos métodos estáticos executa a operação no thread em execução no momento.
Nº Sr. Método e descrição
1
rendimento de vazio estático público()

Faz com que o thread atualmente em execução ceda a quaisquer outros threads de mesma prioridade que estejam aguardando para serem agendados.
2
suspensão vazia estática pública (longo milissegundos)

Faz com que o thread atualmente em execução seja bloqueado por pelo menos o número especificado de milissegundos.
3
public static boolean holdLock(Object x)

Retorna true se o thread atual mantém o bloqueio no objeto fornecido.
4
Thread estático público currentThread()

Retorna uma referência ao thread em execução no momento, que é o thread que invoca esse método.
5
public static void dumpStack()

Imprime o rastreamento de pilha para o thread em execução no momento, o que é útil ao depurar um aplicativo multithread.

Exemplo


O programa ThreadClassDemo a seguir demonstra alguns desses métodos da classe Thread. Considere uma classe DisplayMessage que implementa Executável
// File Name : DisplayMessage.java
// Create a thread to implement Runnable

public class DisplayMessage implements Runnable {
   private String message;
   
   public DisplayMessage(String message) {
      this.message = message;
   }
   
   public void run() {
      while(true) {
         System.out.println(message);
      }
   }
}

A seguir está outra classe que estende a classe Thread -
// File Name : GuessANumber.java
// Create a thread to extentd Thread

public class GuessANumber extends Thread {
   private int number;
   public GuessANumber(int number) {
      this.number = number;
   }
   
   public void run() {
      int counter = 0;
      int guess = 0;
      do {
         guess = (int) (Math.random() * 100 + 1);
         System.out.println(this.getName() + " guesses " + guess);
         counter++;
      } while(guess != number);
      System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**");
   }
}

A seguir está o programa principal, que faz uso das classes definidas acima -
// File Name : ThreadClassDemo.java
public class ThreadClassDemo {

   public static void main(String [] args) {
      Runnable hello = new DisplayMessage("Hello");
      Thread thread1 = new Thread(hello);
      thread1.setDaemon(true);
      thread1.setName("hello");
      System.out.println("Starting hello thread...");
      thread1.start();
      
      Runnable bye = new DisplayMessage("Goodbye");
      Thread thread2 = new Thread(bye);
      thread2.setPriority(Thread.MIN_PRIORITY);
      thread2.setDaemon(true);
      System.out.println("Starting goodbye thread...");
      thread2.start();

      System.out.println("Starting thread3...");
      Thread thread3 = new GuessANumber(27);
      thread3.start();
      try {
         thread3.join();
      } catch (InterruptedException e) {
         System.out.println("Thread interrupted.");
      }
      System.out.println("Starting thread4...");
      Thread thread4 = new GuessANumber(75);
      
      thread4.start();
      System.out.println("main() is ending...");
   }
}

Isso produzirá o seguinte resultado. Você pode tentar este exemplo várias vezes e obterá um resultado diferente a cada vez.

Saída

Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......

Principais conceitos de multithreading de Java


Ao fazer programação multithreading em Java, você precisaria ter os seguintes conceitos muito úteis -

Java

  1. Operadores Java
  2. Comentários Java
  3. Java para cada loop
  4. Strings Java
  5. Interface Java
  6. Classe anônima Java
  7. Java try-with-resources
  8. Anotações Java
  9. Asserções Java
  10. Vetor Java