Multithreading é um ponto de conhecimento muito importante em Java. Aqui, o editor resume o thread Java Multithreading para você, o que é muito útil. Espero que você possa dominar.
1. O ciclo de vida de um tópico e os cinco estados básicos
Em relação ao ciclo de vida dos threads em Java, vamos primeiro olhar para a imagem clássica a seguir:
A figura acima abrange basicamente os importantes pontos de conhecimento da multi-threading em Java. Depois de dominar os pontos de conhecimento na figura acima, você basicamente domina a multi-threading em Java. Incluindo principalmente:
Os threads java têm cinco estados básicos
Novo estado (novo): Quando um par de objetos de thread é criado, ele entra em um novo estado, como: thread t = new mythread ();
Estado pronto (Runnable): Quando o método start () do objeto Thread (t.start ();), o encadeamento entra no estado pronto. Um segmento no estado pronto significa apenas que o thread está pronto e está esperando a CPU agendar a execução a qualquer momento, não que o thread seja executado imediatamente após a execução de t.start ();
Estado em execução: quando a CPU começa a agendar threads no estado pronto, o thread pode ser realmente executado, ou seja, entra no estado em execução. Nota: O estado pronto é a única entrada para o estado em execução, ou seja, se um thread deseja entrar no estado em execução para executar, ele deve estar primeiro no estado pronto;
Estado bloqueado: por algum motivo, um encadeamento no estado em execução desiste temporariamente do uso da CPU e interrompe a execução. Neste momento, entra no estado de bloqueio. Não terá a chance de ser chamado pela CPU novamente para entrar no estado em execução.
De acordo com os motivos do bloqueio, os estados de bloqueio podem ser divididos em três tipos:
1. Aguardando o bloqueio: o thread no estado em execução executa o método wait () para fazer com que o thread entre no estado de bloqueio;
2. Bloqueio sincronizado- o encadeamento falha ao adquirir a trava de sincronização sincronizada (porque a trava é ocupada por outros threads) e entrará no estado de bloqueio sincronizado;
3. Outro bloqueio-o thread entrará em um estado de bloqueio chamando Sleep () ou ingressar () do thread ou emitindo uma solicitação de E/S. Quando o Sleep () State se estendeu, a junção () esperou que o thread termine ou o tempo de tempo ou o processamento de E/S tenha sido concluído, o thread reinseriu para o estado pronto.
Morto: o thread terminou de executar ou sair do método run () devido a uma exceção, e o thread termina seu ciclo de vida.
2. Criação e startup de Java Multithreads
Existem três formas básicas de criação de threads em java
1. Herde a classe de encadeamento e substitua o método run () da classe.
classe mythread estende thread {private int i =; @OverridePublic void run () {for (i =; i <; i ++) {System.out.println (thread.currentThread (). {System.out.println (thread.currentThread (). GetName () + "" + i); if (i ==) {thread mythread = new mythread (); // Crie um novo thread mythread Este thread entra no novo thread de estado mythread = new mythread (); // Crie um novo thread mythread Este thread entra no novo mythread.start (); // Ligue para o método START () para fazer com que o thread entre no mythread.start.start (); // Ligue para o método START () para fazer o thread entrar no estado pronto}}}} Como mostrado acima, herde a classe Thread e substitua o método run (), um novo mythread da classe de encadeamento é definido, onde o corpo do método do método run () representa a tarefa que o encadeamento precisa concluir e é chamado de corpo de execução do encadeamento. Ao criar este objeto de classe de thread, um novo thread é criado e entra no novo estado do thread. Ao chamar o método start () referenciado pelo objeto Thread, o encadeamento entra no estado pronto. No momento, o thread não pode ser executado imediatamente, dependendo do tempo de agendamento da CPU.
2. Implemente a interface executável e substitua o método run () da interface. O método run () também é um corpo de execução de thread, crie uma instância da classe de implementação executável e use essa instância como o destino da classe Thread para criar um objeto Thread. O objeto Thread é o objeto de encadeamento real.
classe MyRunnable implementa runnable {private int i =; @OverridePublic void run () {for (i =; i <; i ++) {System.out.println (thread.currentThread (). getName ()+""+i); {System.out.println (thread.currentThread (). GetName () + "" + i); if (i ==) {runnable myRunnable = new MyRunnable (); // Crie um objeto da classe de implementação executável thread thread = novo thread (myRunnable); // Use MyRunnable como um alvo de encadeamento para criar um novo thread Thread = novo thread (myRunnable); thread.start (); // Ligue para o método start () para fazer o thread entrar no thread de estado pronto.start ();}}}} Eu acredito que todos estão familiarizados com as duas maneiras acima de criar novos tópicos. Então, qual é a relação entre Thread e Runnable? Vamos primeiro olhar para o exemplo a seguir.
public class ThreadTest {public static void main (string [] args) {for (int i =; i <; i ++) {system.out.println (thread.currentThread (). getName () + "" + i); if (i ==) {runnable myRunnable = new MyRunnable (); if (i ==) {runnable myRunnable = novo myRunnable (); Mythread (myRunnable); thread.start ();}}}} classe myRunnable implementa runnable {private int i =; @OverridePublic void run () {System.out.println ("in myRunnable run"); para (i =; i <; i ++) {system.out.out.out.out.Int.Int. " +i);}}} classe mythread estende o thread {private int i =; public mythread (runnable runnable) {super (runnable);}@substituirpublic void run () {system.out.println (" no mythread run "); para (i =; i <; "" + i);}}} Da mesma forma, o mesmo vale para criar tópicos que implementam a interface executável, a diferença é que
Thread Thread = novo mythread (myRunnable);
Então, esse método pode criar com sucesso um novo thread? A resposta é sim. Quanto ao corpo de execução do thread neste momento, o método run () está na interface Mirunnable ou no método run () na classe Mythread? Através da saída, sabemos que o corpo de execução do encadeamento é o método run () na classe Mythread. De fato, o motivo é muito simples, porque a classe Thread em si também implementa a interface executável e o método run () é definido pela primeira vez na interface executável.
interface pública runnable {public abstrate void run ();} Vamos dar uma olhada na implementação do método run () na interface executável na classe Thread:
@OverridePublic void run () {if (Target! = Null) {Target.run ();}} Ou seja, ao executar o método run () na classe Thread, o método run () no destino será determinado primeiro. Se existir, o método run () no destino é executado, ou seja, o método run () na classe que implementa a interface executável e substitui o método run (). No entanto, nas colunas dadas acima, devido à existência de polimorfismo, o método run () na classe Thread não é executado, mas o tipo de tempo de execução, ou seja, o método run () na classe Mythread é executado diretamente.
3. Crie threads usando interfaces chamáveis e futuras. Especificamente, ele cria uma classe de implementação para a interface chamada e implementa o método clall (). E use a classe FutureTask para envolver o objeto Class de implementação chamável e use este objeto FutureTask como o alvo do objeto Thread para criar um thread.
Parece um pouco complicado, mas ficará claro se você olhar diretamente para um exemplo.
classe pública threadtest {public static void main (string [] args) {callable <Teger> myCallable = new MyCallable (); // Crie objeto MyCallable FutureTask <TEGER> ft = new FutureTask <Integer> (MyCallable); // Use o FutureTask para envolver o objeto MyCallable para (int i =; i <; i ++) {System.out.println (thread.currentThread (). GetName () + "" + i); if (i ==) {thread thread = new Thread (ft); // Objeto FutureTask cria um novo thread como um alvo do thread objeto Thread.start (); // Thread entra no estado pronto}} System.out.println ("Tópico principal para execução de loop concluída ..."); tente {int sum = ft.get (); // obtenha o resultado retornado pelo método Call () no recém -criado New Thread System.out.println ("Sum =" + Sum);} Catch (interruptEdException e) {E.PrintStackTrace ();}} Catch (ExecutionException E) {E.PrintStackTrace ();}}} ClassplentMlesslelable E) {E.PrintStackTrace ();}}}} myClall Método, o método Call () possui o valor de retorno @OverridePublic Integer Call () {int sum =; para (; i <; i ++) {System.out.println (thread.currentThread (). getName () +"" +i); soma += i;} soma;}}}}}} Primeiro de tudo, descobrimos que, ao implementar a interface chamada, o método run () não é mais o método run (), mas o método Call (). Este método Call () é o corpo de execução do thread e também tem um valor de retorno! Ao criar um novo thread, o objeto MyCallable é embrulhado através do FutureTask e também é usado como um alvo para o objeto Thread. Em seguida, observe a definição da classe FutureTask:
classe pública FutureTask <V> implementa RunnableFuture <V> {// ....} interface pública RunnableFuture <V> estende Runnable, Future <V> {void run ();} Portanto, descobrimos que a classe FutureTask implementa interfaces executáveis e futuras, o que faz com que as características duplas do futuro e da execução. Através do recurso Runnable, ele pode ser usado como um alvo do objeto Thread, e o recurso futuro permite obter o valor de retorno do método Call () no thread recém -criado.
Depois de executar este programa, descobrimos que a soma = 4950 é sempre a última saída. "O encadeamento principal do loop foi executado ..." É provável que seja emitido no meio do loop de rosca infantil. Do mecanismo de agendamento de threads da CPU, sabemos que não há problema com o tempo de saída de "o encadeamento principal para o loop foi executado ...", então por que soma = 4950 será a saída para sempre?
O motivo é que, quando o método Call () do encadeamento da criança é obtido através do método ft.get (), quando o método do thread da criança ainda não foi executado, o método ft.get () bloqueará até que o método Call () seja executado antes que o valor de retorno possa ser obtido.
O acima explica principalmente três métodos de criação de roscas comuns. Para a inicialização dos threads, todos eles são chamados de método start () do objeto Thread. É importante observar que o método start () não pode ser chamado duas vezes no mesmo objeto de encadeamento.
Iii. Status pronto, de corrida e morte do Java Multithreading
O estado pronto é convertido para o estado em execução: quando este thread obtém o recurso do processador;
O estado de corrida é convertido para o estado pronto: quando esse thread chama ativamente o método de rendimento () ou perde os recursos do processador durante a execução.
O estado de corrida é convertido para o estado morto: quando o órgão de execução do thread é concluído ou ocorre uma exceção.
Deve -se notar aqui que, quando o método de rendimento () do encadeamento for chamado, o encadeamento transita do estado em execução para o estado pronto, mas que encadeamento no estado pronto na CPU está agendado tem uma certa aleatoriedade. Portanto, pode ocorrer que, depois que o encadeamento A chama o método de rendimento (), a CPU ainda agenda o encadeamento A.
Devido às necessidades comerciais reais, é frequentemente encontrado que um tópico precisa ser encerrado em uma oportunidade específica para fazê -lo entrar em um estado morto. O método mais comum no momento é definir uma variável booleana e, quando as condições forem atendidas, o corpo de execução do encadeamento será executado rapidamente. como:
classe pública threadtest {public static void main (string [] args) {myRunnable myRunnable = new myRunnable (); thread thread = new Thread (myRunnable); para (int i =; i <; i ++) {System.out.println (thread.currentThread (). {thread.start ();} if (i ==) {myRunnable.stopthread ();}}}} classe myRunnable implementa runnable {private boolean stop; @OverridePublic void run () {para (int i; " + i);}} public void stopThread () {this.stop = true;}}O exposto acima é uma análise abrangente do thread java multi-threading que o editor apresentou a você. Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!