1. Conceitos básicos de threads
Entendimento de threads: Thread é um caminho de execução diferente em um programa
Cada ramo é chamado de encadeamento e Main () é chamado de ramo principal, também chamado de encadeamento principal.
Um processo é apenas um conceito estático, um arquivo .class na máquina, um arquivo .exe na máquina, isso é chamado de processo. O processo de execução do programa é assim: primeiro, coloque o código do programa na área de código da memória. Depois que o código é colocado na área de código, ele não começa a executar imediatamente. No entanto, isso significa que um processo está pronto para começar. O processo foi gerado, mas ainda não começou a executar. Esse é o processo, portanto, o processo é realmente um conceito estático e não pode ser movido por si só. A execução usual do processo refere -se ao encadeamento principal do processo que começa a executar, ou seja, o método principal () começa a executar. Os processos são um conceito estático e, na verdade, os threads são executados em nossas máquinas.
O sistema operacional Windows suporta multi-threading. Ele pode executar muitos threads ao mesmo tempo e também suporta vários processos. Portanto, o sistema operacional Windows é um sistema operacional que suporta multi-threading e multipocessamento. Linux e Uinux também são sistemas operacionais que suportam multi-threading e multiprocessamento. O DOS não suporta multi-threading e multipocessamento. Ele suporta apenas processos únicos. Apenas um processo é executar no mesmo momento, que é chamado de threading único.
A CPU é realmente poderosa e capaz de executar tantos programas ao mesmo tempo? Não, a execução da CPU é a seguinte: A CPU é muito rápida e pode ser contada centenas de milhões de vezes em um segundo, então a CPU divide seu tempo em pequenas fatias de tempo. Eu executo desta vez a fatia por um tempo, na próxima vez que a fatia o executará por um tempo, e na próxima vez que a fatia executará outras pessoas por um tempo. Embora existam dezenas de threads, eles podem ser executados em um tempo muito curto. Mas para nós humanos, a velocidade de execução da CPU é muito rápida, por isso parece que está executando ao mesmo tempo, mas, na verdade, em um momento, há apenas um thread em execução na CPU.
Primeiro de tudo, você precisa entender três conceitos ao aprender tópicos :
1. Processo: o processo é um conceito estático
2. Tópico: Existe um thread principal em um processo chamado MAIN (), que é um programa e um caminho de execução diferente em um processo.
3. Ao mesmo tempo, uma CPU pode suportar apenas um thread para executar. Como a CPU funciona muito rápido, parecemos que somos multithreading.
O que é verdadeiro multithreading? Se sua máquina possui CPUs duplas ou núcleos duplos, ela é realmente multi-thread.
2. Criação e startup de threads
Em Java, os threads java são implementados através da classe java.lang.thread, e cada objeto Thread representa um novo thread. Existem duas maneiras de criar um novo thread: o primeiro é herdar da classe Thread, e a outra é implementar a interface executada. Quando a VM iniciar, haverá um encadeamento definido pelo método principal (public estático void main ()), e esse thread é chamado de encadeamento principal. Novos threads podem ser criados criando instâncias de threads. Você só precisa ser um novo objeto de thread, e um novo thread aparecerá. Cada encadeamento completa sua operação através do método execute () correspondente a um objeto de encadeamento específico. O método run () é chamado de corpo de rosca.
Exemplo 1: Crie e inicie um novo thread usando a implementação da interface executável
Crie um novo tópico para chamar o método de execução
pacote cn.galc.test; public class testhread1 {public static void main (string args []) {runner1 r1 = new runner1 (); // aqui novo objeto da classe Thread sai // r1.run (); // Isso é chamado de chamada de método. A execução da chamada do método é esperar até que o método RUN () seja executado antes que o método Main () continuará sendo executado. Thread t = novo encadeamento (r1); // Para iniciar um novo thread, você deve novo objeto Thread sai // Thread (Target Runnable) é usado aqui. O construtor t.start (); // inicia o thread recém -aberto, o novo thread executa o método run (), e o novo thread e o encadeamento principal serão executados em paralelo para (int i = 0; i <10; i ++) {System.out.println ("maintheod:"+i); }}}/*Defina uma classe para implementar a interface executável. Implementar a interface executável significa que esta classe é uma classe de thread*/class Runner1 implementa runnable {public void run () {for (int i = 0; i <10; i ++) {System.out.println ("runner1:"+i); }}}O processo de execução de programas multithread é o seguinte:
Chame o método Run diretamente sem abrir um novo tópico
Os resultados da operação são os seguintes:
Exemplo 2: Herite a classe Thread e substitua seu método run () para criar e iniciar um novo thread
pacote cn.galc.test;/*O segundo método de criação e inicialização do encadeamento: defina uma subclasse do thread e implemente o método run ()*/public class TestThread2 {public static void main (string args []) {runner2 r2 = new Runner2 (); r2.start (); // Ligue para o método start () para iniciar o thread recém -aberto para (int i = 0; i <= 10; i ++) {System.out.println ("mainMethod:"+i); }}}/*Classe RUNNER2 herda da classe Thread, instanciando um objeto da classe Runner2, você pode abrir um novo thread. Ligue para o método START () herdado da classe Thread. Você pode iniciar o thread recém -aberto*/class Runner2 estende o thread {public void run () {// reescreva a implementação do método run () para (int i = 0; i <= 10; i ++) {System.out.println ("runner2:"+i); }}}A escolha de usar dois métodos para criar novos threads, a saber, implementar a interface executável e herdar a classe Threads, deve ter prioridade para abrir um novo thread. Como a implementação de uma interface pode implementar múltiplas, a herança de uma classe pode ser apenas uma única herança. Portanto, quando você pode usar a interface executável ao abrir um novo thread, tente não usar a herança da classe Thread para abrir novos threads.
3. Transição do estado dos threads
3.1. Métodos básicos de controle de roscas
3.2. Introdução ao método de sono/junção/rendimento
Exemplo de aplicação do método do sono:
pacote cn.galc.test; importar java.util.*; public class TestThread3 {public static void main (string args []) {mythread thread = new mythread (); thread.start (); // Ligue para o método start () para iniciar o thread recém -aberto, tente {/*thread.sleep(10000); O método do sono () é um método estático declarado na classe Thread, para que você possa usar o formato de Thread.sleep () para chamar * / /*mythread.sleep(10000); A classe Mythread herda a classe de threads e naturalmente também herda o método Sleep (), para que você também possa chamá -lo usando o formato do mythread.sleep () *// *A chamada de métodos estáticos pode ser chamada diretamente na forma de "Nome do método da classe. System.out.println ("O thread principal dorme por 10 segundos e começa novamente"); // Ao chamar o método estático de outra classe no método Main (), você precisa usar o método "Class.static Method, onde o método estático está localizado" para chamar /*, então aqui é deixar o encadeamento principal dormir por 10 segundos. Qual thread chama o método Sleep (), então agora o thread principal dorme. */} catch (interruptEdException e) {e.printStackTrace (); } //thread.interrupt() ;//use Interrupt () Método para encerrar a execução de um thread.flag = false; // altere as condições do loop e encerrar o loop morto/** * Quando uma interrupção ocorrer, defina diretamente a condição do loop para sair do loop morto, * então encerre a execução do encadeamento da criança. Esta é uma maneira melhor de encerrar o thread filho* / / *** Calling Interrupt () Método para quebrar o fio em execução é equivalente a derramar uma panela de água fria no fio principal e quebrar o sub-thread em execução. Após a interrupção do sub-thread de execução, será lançada uma interrupção interrompida, que executará a instrução Retorno e encerrará a execução do thread. So the sub-thread here ends the execution of the thread after 10 seconds of execution*/ }}class MyThread extends Thread { boolean flag = true;// Define a tag to control the conditions of the loop public void run() { /* * Note: Here, you cannot write throw Exception directly behind the run() method to throw exceptions, * Because now we need to rewrite the run() method inherited from the Thread class, the rewrite O método não pode lançar exceções diferentes do método reescrito. * Então, aqui você só pode escrever, tente ... Catch () para capturar exceções*/ while (sinalizador) { System.out.println("======================================================================================================== ================================================================ ================================================================ ================================================================ ================================================================ ================================================================ ================================================================= Obviamente, não está errado chamá -lo usando o formato de "nome da classe. Nome do método"*/ // mythread.sleep (1000); // use o formato de "nome da classe. Nome do método" para chamar o método estático (1000); depois, se houver, se o sleep de um thread, que é o sleep, que é o seguinte. Iniciado a cada segundo em um loop morto, e o tempo atual do sistema é impresso a cada segundo} captura (interrompida e) { /** ao dormir, um prato de água fria pode interromper o sono*, portanto, quando a linha em execução é interrompida por alguns motivos inesperados, uma exceção que é interrompida (interrupta) pode ser tocada e a devolução; }}Resultados em execução:
Exemplo de método de junção:
pacote cn.galc.test; public class TestThread4 {public static void main (string args []) {mythread2 thread2 = new mythread2 ("mythread"); // Ao criar um novo objeto de thread, nomeie o objeto Mythread Thread2.start (); // Iniciar o thread Try {Thread2.Join (); // Ligue para o método junção () para mesclar o thread, mesclar o mythread do thread da criança no thread // Após a fusão do thread, o processo de execução do programa é equivalente ao processo de execução do método} } para (int i = 0; i <= 5; i ++) {System.out.println ("Eu sou o thread principal"); }}} classe mythread2 estende thread {mythread2 (string s) {super (s); / * * Use a palavra super -chave para chamar o construtor da classe pai * um dos construtores do thread da classe pai: "Public Thread (Nome da String)" * Através de um construtor, o thread recém -aberto pode ser nomeado, que facilita o gerenciamento de threads */} public void Run () {para (int i = 1; i <= 5; getName ()); // use // public final string getName () definido no thread da classe pai, retorna o nome deste thread. tente {dormir (1000); // Faça o fio filho dormir por 1 segundo toda vez que for executado} captura (interruptedException e) {return; }}}}Resultados em execução:
Exemplo de uso do método de rendimento:
pacote cn.galc.test; public class TestThread5 {public static void main (string args []) {mythread3 t1 = new mythread3 ("t1"); /* Dois threads infantis T1 e T2 foram abertos ao mesmo tempo. T1 e T2 Executam o método RUN ()*//*Há um total de 3 threads em paralelo durante a execução deste programa, ou seja, os threads infantis T1 e T2 e o encadeamento principal*/ mythread3 T2 = novo mythread3 ("T2"); t1.start (); // thread de crianças iniciantes t1 t2.start (); // thread infantil inicial t2 para (int i = 0; i <= 5; i ++) {System.out.println ("Eu sou o thread principal"); }}} classe mythread3 estende thread {mythread3 (string s) {super (s); } public void run () {for (int i = 1; i <= 5; i ++) {System.out.println (getName () + ":" + i); if (i % 2 == 0) { yield();// When the execution reaches i can be divided by 2, the current thread executing is given out and let another thread executing the run() method be executed first/* * You can see during the running of the program, * When thread t1 is executed (i%2==0) times, it will give out the thread and let the t2 thread execute first*, and when thread t2 is executed (I%2 == 0) vezes, ele fornecerá o thread ao thread T1 para a execução prioritária */}}}Os resultados da operação são os seguintes:
O exposto acima é todo o conteúdo deste artigo. Esperamos que isso possa ajudá -lo.