Java/Thread: diferenças entre revisões

Origem: Wikilivros, livros abertos por um mundo aberto.
[edição verificada][edição verificada]
Conteúdo apagado Conteúdo adicionado
Linha 25: Linha 25:


==Criando threads==
==Criando threads==
Para criar sua própria ''thread'' por meio da classe <code>Thread</code>, é preciso realizar 3 etapas: Definir o código a ser executado pela ''thread'', referenciar esse código em uma instância de <code>Thread</code> e chamar o método <code>void start()</code> dessa classe.


===Definindo o código===
<source lang="java">
O código que será executado por uma ''thread'' deve ser definido no método <code>void run()</code> da interface <code>[https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html java.lang.Runnable]</code>.
Thread()
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(String name)
</source>

O código executado por uma ''thread'' pode ser definido de duas formas: através de subclasse da classe <code>Thread</code> ou da implementação da interface <code>java.lang.Runnable</code>. Em ambos os casos as instruções devem estar inseridas no corpo do método <code>void run</code>.


<source lang="Java" highlight="1,4">
Os construtores que não especificam em sua lista de parâmetros variável do tipo <code>Runnable</code> devem ser chamados em uma subclasse de <code>Thread</code>.
class Executavel implements Runnable {
<source lang="java" highlight="4">
public class Segmento extends Thread {

public Segmento(String nome) {
super(nome);
}


@Override
@Override
public void run() {
public void run() {
System.out.println(Thread.currentThread());
// Código
}
}
}
}
</source>


Já que <code>Runnable</code> é uma interface funcional, é possível reescrever o código acima da seguinte forma.

<source lang="Java" highlight="1,4">
Runnable runnable = () -> System.out.println(Thread.currentThread());
</source>
</source>


===Instanciando a classe Thread===
Isso ocorre porque o método <code>void run</code> de <code>Thread</code> chama o método <code>void run</code> de sua variável <code>Runnable target</code>, caso <code>target</code> não seja uma referência nula.
<source lang="Java" highlight="5">
class EstudandoThreads {

public static void main(String[] args) {
Runnable runnable = () -> System.out.println(Thread.currentThread());
Thread thread = new Thread(runnable);
}
}
</source>

===Executando a thread===
<source lang="Java" line start=3 highlight="6">
class EstudandoThreads {

public static void main(String[] args) {
Runnable runnable = () -> System.out.println(Thread.currentThread());
Thread thread = new Thread(runnable);
thread.start();
}
}
</source>
Thread[Thread-0,5,main]


Na próxima seção será explicado o porquê de <code>Runnable</code> ser uma escolha melhor que <code>Thread</code> para definir o código a ser executado por uma ''thread''.


<code>String name</code> especifica um nome para a ''thread''. Caso não especificado no construtor o nome da ''thread'' será criado automaticamente derivado do modelo '''Thread-0''', onde '''0''' é um número incrementado a cada nova '''thread''' criada sem definição de nome.
<code>String name</code> especifica um nome para a ''thread''. Caso não especificado no construtor o nome da ''thread'' será criado automaticamente derivado do modelo '''Thread-0''', onde '''0''' é um número incrementado a cada nova '''thread''' criada sem definição de nome.




===Evite ThreadGroup===
<source lang="Java">
<source lang="Java">
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target)
Linha 64: Linha 85:


<code>[https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html java.lang.ThreadGroup] group</code> inclui a ''thread'' em um grupo de ''threads''. A utilização de <code>ThreadGroup</code> deve ser evitada<ref>Item 73 - JOSHUA, Bloch. Effective Java. 2.ª edição, 2009. </ref>.
<code>[https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadGroup.html java.lang.ThreadGroup] group</code> inclui a ''thread'' em um grupo de ''threads''. A utilização de <code>ThreadGroup</code> deve ser evitada<ref>Item 73 - JOSHUA, Bloch. Effective Java. 2.ª edição, 2009. </ref>.

===A interface Runnable===
A interface funcional <code>[https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html java.lang.Runnable]</code> especifica o método <code>void run()</code>. Esse método deverá conter o código a ser executado por uma ''thread''.

<source lang="java">

</source>


==Métodos estáticos==
==Métodos estáticos==

Revisão das 10h44min de 28 de julho de 2016

Cada objeto gerado pela classe java.lang.Thread cria uma thread. Também conhecida em línguas lusófonas como linha de execução.

Cada uma dessas linhas de execução podem ser executadas em paralelo, possibilitando à aplicação a execução de instruções relativamente simultâneas.

A thread main

Toda aplicação tem ao menos uma thread, não-daemon, em tempo de execução: a thread main.

A thread main, criada automaticamente pela JVM quando uma aplicação é iniciada, é responsável por executar o código inicial da aplicação (comumente inserido no corpo do método public static void main(String... args)).

public static void main(String... args) {
    Thread t = Thread.currentThread();
    String nome = t.getName();
    long id = t.getId();
    System.out.println("Nome: " + nome + ", id: " + id);
}
Nome: main, id: 1

Thread Thread.currentThread() devolve uma referência do objeto Thread correspondente à thread que executa a chamada desse método. No código acima, foi devolvida uma referência à thread main.

String getName() foi utilizado para obter o nome da thread, complementarmente há o método void setName(String) que altera o nome da thread.

long getId() devolve um long automaticamente atribuído quando a thread é criada. Esse valor é único e não é reutilizado quando a thread morre.

Criando threads

Para criar sua própria thread por meio da classe Thread, é preciso realizar 3 etapas: Definir o código a ser executado pela thread, referenciar esse código em uma instância de Thread e chamar o método void start() dessa classe.

Definindo o código

O código que será executado por uma thread deve ser definido no método void run() da interface java.lang.Runnable.

class Executavel implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread());	
    }
}

Já que Runnable é uma interface funcional, é possível reescrever o código acima da seguinte forma.

Runnable runnable = () -> System.out.println(Thread.currentThread());

Instanciando a classe Thread

class EstudandoThreads  {

    public static void main(String[] args) {
        Runnable runnable = () -> System.out.println(Thread.currentThread());
	Thread thread = new Thread(runnable);
    }
    
}

Executando a thread

class EstudandoThreads  {

    public static void main(String[] args) {
        Runnable runnable = () -> System.out.println(Thread.currentThread());
	Thread thread = new Thread(runnable);
	thread.start();
    }
    
}
Thread[Thread-0,5,main]


String name especifica um nome para a thread. Caso não especificado no construtor o nome da thread será criado automaticamente derivado do modelo Thread-0, onde 0 é um número incrementado a cada nova thread criada sem definição de nome.


Evite ThreadGroup

Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, String name)

java.lang.ThreadGroup group inclui a thread em um grupo de threads. A utilização de ThreadGroup deve ser evitada[1].

Métodos estáticos

activeCount()
currentThread()
dumpStack()
enumerate(Thread[] tarray)
getAllStackTraces()
getDefaultUncaughtExceptionHandler()
holdsLock(Object obj)
interrupted()
setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
sleep(long millis)
sleep(long millis, int nanos)
yield()

Métodos de instância

checkAccess()
countStackFrames()
getContextClassLoader()
getId()
getName()
getPriority()
getState()
getThreadGroup()
getUncaughtExceptionHandler()
interrupt()
isAlive()
isDaemon()
isInterrupted()
join()
join(long millis)
join(long millis, int nanos)
run()
setContextClassLoader(ClassLoader cl)
setDaemon(boolean on)
setName(String name)
setPriority(int newPriority)
setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
start()
  1. Item 73 - JOSHUA, Bloch. Effective Java. 2.ª edição, 2009.