Breve introdução ao Java Thread.yield ()

Breve introdução ao Java Thread.yield ()

1. Visão geral

Neste tutorial, vamos explorar o métodoyield() na classeThread.

Vamos compará-lo com outras expressões idiomáticas de simultaneidade disponíveis em Java e, eventualmente, explorar suas aplicações práticas.

2. Sinopse deyield()

Como a documentação oficial sugere,yield() fornece um mecanismo para informar o "planejador" quethe current thread is willing to relinquish its current use of processor but it’d like to be scheduled back soon as possible.

O "planejador" é livre para aderir ou ignorar essas informações e, de fato, possui um comportamento variável, dependendo do sistema operacional.

O seguinte fragmento de código exibe dois threads com a mesma prioridade, gerando após cada agendamento:

public class ThreadYield {
    public static void main(String[] args) {
        Runnable r = () -> {
            int counter = 0;
            while (counter < 2) {
                System.out.println(Thread.currentThread()
                    .getName());
                counter++;
                Thread.yield();
            }
        };
        new Thread(r).start();
        new Thread(r).start();
    }
}

Quando tentamos executar o programa acima várias vezes, obtemos resultados diferentes; alguns deles são mencionados abaixo:

Execução 1:

Thread-0
Thread-1
Thread-1
Thread-0

Execução 2:

Thread-0
Thread-0
Thread-1
Thread-1

Como você pode ver, o comportamento deyield() não é determinístico e também depende da plataforma.

3. Comparando com outros idiomas

Existem outras construções para afetar a progressão relativa dos encadeamentos. Eles incluemwait(),notify() enotifyAll() como parte da classeObject,join() como parte da classeThread esleep() como parte da classeThread.

Vamos ver como eles se comparam ayield().

3.1. yield() vswait()

  • Enquantoyield() é invocado no contexto do thread atual,wait() só pode ser invocado em um bloqueio explicitamente adquirido dentro de um bloco ou método sincronizado

  • Ao contrário deyield(), é possível esperar() para especificar um período de tempo mínimo para aguardar antes de qualquer tentativa de agendar o thread novamente

  • Comwait() também é possível despertar o thread a qualquer momento por meio de uma invocação denotify() ounotifyAll() no objeto de bloqueio em questão

3.2. yield() vssleep()

  • Enquantoyield() só pode fazer uma tentativa heurística de suspender a execução da thread atual sem garantia de quando será agendada de volta,sleep() pode forçar o planejador a suspender a execução da thread atual para às pelo menos o período de tempo mencionado como seu parâmetro.

3.3. yield() vsjoin()

  • O encadeamento atual pode invocarjoin() em qualquer outro encadeamento, o que faz com que o encadeamento atual espere que o outro termine antes de prosseguir

  • Opcionalmente, ele pode mencionar um período como parâmetro, que indica o tempo máximo pelo qual o encadeamento atual deve esperar antes de continuar

4. Uso parayield()

Como a documentação oficial sugere, raramente é necessário usaryield()e, portanto, deve ser evitado, a menos que seja muito claro com os objetivos à luz de seu comportamento.

No entanto, alguns dos usos parayield() incluem projetar construções de controle de simultaneidade, melhorar a capacidade de resposta do sistema em um programa de computação pesada etc.

No entanto, esses usos devem ser acompanhados por perfis detalhados e comparações para garantir o resultado desejado.

5. Conclusão

Neste breve artigo, discutimos o métodoyield() na classeThread e vimos seu comportamento e limitações por meio de um fragmento de código.

Também exploramos sua comparação com outros idiomas de simultaneidade disponíveis em Java e, finalmente, examinamos alguns dos casos de uso em queyield() pode ser útil.

Como sempre, você pode verificar os exemplos fornecidos neste artigoover on GitHub.