Muitas perguntas principais da entrevista em Java vêm de estruturas de multi-threading e coleções. Experiência prática proficiente é necessária ao entender o conceito de tópicos principais. Este artigo coleta algumas perguntas típicas sobre o Threading Java, que geralmente são feitas por engenheiros seniores.
0. O que é a sincronização multithread em Java?
Em programas multithread, a sincronização pode controlar o acesso a recursos compartilhados. Se não houver sincronização, quando um thread Java está modificando uma variável compartilhada, outro thread está usando ou atualizando a mesma variável, que pode facilmente levar a resultados incorretos no programa.
1. Explique várias maneiras de implementar multi-threading?
Um encadeamento Java pode implementar a interface executável ou herdar a classe Thread para implementá -la. Quando você planeja herdar várias vezes, você prefere implementar o Runnable.
2. Qual é a diferença entre thread.start () e thread.run ()?
O método Thread.start () (nativo) inicia o thread e entra no estado pronto. Quando a CPU aloca tempo para o thread, os horários da JVM para executar o método run ().
3. Por que precisamos dos métodos de execução () e start ()? Podemos apenas usar o método run () para concluir a tarefa?
Precisamos dos dois métodos de run () & start () porque a JVM cria um encadeamento separado diferente da chamada dos métodos comuns, portanto este trabalho é realizado pelo método de início do thread. O início é implementado pelo método local e precisa ser chamado de exibição. Outra vantagem de usar esses dois métodos é que qualquer objeto pode ser executado como um thread. Enquanto a interface executável for implementada, isso evita os múltiplos problemas de herança do Java causados pela herdeira da classe Thread.
4. Qual é a classe Threadlocal e como usá -la?
Threadlocal é uma variável local no nível da linha, não um "Thread Local". O ThreadLocal fornece uma cópia independente da variável para cada thread que usa a variável. Cada encadeamento não afeta a cópia de outros objetos de encadeamento ao modificar a cópia (nota do tradutor).
Aqui estão os pontos -chave das variáveis locais de thread:
Uma variável local de thread (variável ThreadLocal) fornece convenientemente uma variável separada para cada encadeamento.
As instâncias Threadlocal geralmente aparecem em uma classe como campos estáticos privados (estáticos privados), que são usados para associar um thread.
Quando vários threads acessam instâncias de threadlocal, cada thread mantém uma cópia independente das variáveis fornecidas pelo ThreadLocal.
Os usos comumente usados podem ser vistos no modo DAO. Quando a classe Dao é uma classe singleton, a conexão do banco de dados é mantida independentemente por cada encadeamento e não se afeta. (Singleton baseado em thread)
5. Quando a InvalidMonitorStateException será lançada e por quê?
Ao ligar para qualquer um dos métodos em espera ()/notify ()/notifyAll (), se o encadeamento atual não obtiver a trava do objeto, uma exceção de ilegalMonitorStateException será lançada (ou seja, quando o programa não executará qualquer bloco de sincronização ou método de sincronização do objeto, ele ainda é chamado de espera ()/Notify ()/Notify ()/não. Como a exceção é uma subclasse do RuntimeExcpetion, a exceção não precisa ser pega (embora você possa pegá -lo o tempo que desejar). Como tempo de execução, essas exceções não são mencionadas na assinatura do método wait (), notify (), notifyAll ().
6. Qual é a diferença entre Sleep (), Suspender () e Wait ()?
Thread.sleep () fabrica o thread atual em um estado "não executável" no horário especificado. O thread sempre segura o monitor do objeto. Por exemplo, se um thread estiver atualmente em um bloqueio de sincronização ou método de sincronização, outros threads não podem entrar no bloco ou método. Se outro thread chamar o método interromp (), ele acordará o tópico "dormindo".
Nota: Sleep () é um método estático. Isso significa que ele é válido apenas para o thread atual e um erro comum é chamando T.Sleep (), (aqui é um thread que é diferente do encadeamento atual). Mesmo que o t.sleep () seja executado, o encadeamento atual vai dormir, não o thread t. t.suspend () é um método desatualizado. O uso do suspense () faz com que o thread insira um estado estagnado. O encadeamento sempre segura o monitor do objeto e o suspensão () provavelmente causará problemas de impasse.
object.wait () faz com que o tópico atual saia de um estado "invasor". Ao contrário do Sleep (), a espera é um método de objeto em vez de thread. Ao chamar objeto.wait (), o thread precisa primeiro obter o bloqueio do objeto desse objeto. O encadeamento atual deve manter o objeto de trava sincronizado e adicionar o encadeamento atual à fila de espera. Em seguida, outro thread pode sincronizar o mesmo objeto Lock para chamar Object.Notify (), que acordará o encadeamento que estava esperando originalmente e depois soltará o bloqueio. Basicamente, aguarde ()/notify () é semelhante ao Sleep ()/Interrupt (), exceto que o primeiro exige que o bloqueio de objeto seja adquirido.
7. O que acontece ao usar a sincronização em métodos estáticos?
Ao sincronizar um método estático, o objeto "classe" da classe será obtido. Portanto, quando um encadeamento entra em um método estático sincronizado, o monitor de thread adquire o bloqueio do objeto da própria classe e outros threads não podem inserir nenhum método de sincronização estática desta classe. Não é como um método de instância, porque vários threads podem acessar diferentes instâncias, simultaneamente, métodos de instância síncronos.
8. Quando um método de sincronização foi executado, o encadeamento pode chamar o método de instância assíncrono no objeto?
Sim, um método assíncrono sempre pode ser chamado sem problemas. De fato, o Java não faz nenhum cheque para métodos assíncronos, e os objetos de bloqueio são verificados apenas em métodos de sincronização ou blocos de código síncrono. Se um método não for declarado síncrono, mesmo se você estiver usando dados compartilhados, o Java ainda o chamará sem verificar se é seguro, seja especialmente cuidadoso neste caso. Se um método é declarado síncrono depende do acesso à seção crítica. Se o método não acessar a seção crítica (recursos compartilhados ou estruturas de dados), não será necessário declarar síncrono.
Aqui está um exemplo: a classe comum possui dois métodos sincronizadosMethod1 () e Method1 (), e a classe Mythread chama esses dois métodos em um thread independente.
classe pública Common {public sincronizada void synchronizedMethod1 () {System.out.println ("SynchronizedMethod1 chamado"); tente {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("SynchronizedMethod1 done"); } public void method1 () {System.out.println ("Método 1 chamado"); tente {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("Método 1 feito"); }} classe pública mythread estende thread {private int id = 0; Common Private Common; public mythread (nome da string, int não, objeto comum) {super (nome); comum = objeto; id = não; } public void run () {System.out.println ("Execução do thread" + this.getName ()); tente {if (id == 0) {Common.synchronizedMethod1 (); } else {Common.method1 (); }} catch (Exceção e) {e.printStackTrace (); }} public static void main (string [] args) {Common c = new Common (); Mythread t1 = novo mythread ("mythread-1", 0, c); Mythread t2 = novo mythread ("mythread-2", 1, c); t1.start (); t2.start (); }}Aqui está a saída do programa:
Executando ThreadMythRead-1
SynchronizedMethod1 chamado
Executando ThreadMythRead-2
Método 1 chamado
SynchronizedMethod1 feito
Método 1 feito
Os resultados mostram que, mesmo que o método SynchronizedMethod1 () seja executado, o método1 () será chamado.
9. Dois threads podem chamar dois métodos diferentes de instância síncrona em um objeto?
Não, como um objeto sincronizou o método da instância, o thread adquire o bloqueio do objeto do objeto. Portanto, outros métodos de sincronização só podem ser executados após a liberação do método após a liberação do bloqueio do objeto. O exemplo de código a seguir é muito claro: a classe Common possui métodos sincronizadosMethod1 () e SynchronizedMethod2 (), e o mythread chama esses dois métodos.
classe pública Common {public sincronizada void synchronizedMethod1 () {System.out.println ("SynchronizedMethod1 chamado"); tente {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("SynchronizedMethod1 done"); } public sincronizado void synchronizedMethod2 () {System.out.println ("SynchronizedMethod2 chamado"); tente {thread.sleep (1000); } catch (interruptedException e) {e.printStackTrace (); } System.out.println ("SynchronizedMethod2 done"); }} classe pública mythread estende thread {private int id = 0; Common Private Common; public mythread (nome da string, int não, objeto comum) {super (nome); comum = objeto; id = não; } public void run () {System.out.println ("Execução do thread" + this.getName ()); tente {if (id == 0) {Common.synchronizedMethod1 (); } else {Common.synchronizedMethod2 (); }} catch (Exceção e) {e.printStackTrace (); }} public static void main (string [] args) {Common c = new Common (); Mythread t1 = novo mythread ("mythread-1", 0, c); Mythread t2 = novo mythread ("mythread-2", 1, c); t1.start (); t2.start (); }}10. O que é um impasse
Um impasse significa que dois ou mais threads são infinitamente bloqueados e os threads estão esperando um pelo outro pelos recursos necessários. Isso pode acontecer quando dois threads tentam adquirir bloqueios para outros recursos, e cada thread está aguardando indefinidamente a liberação de outros bloqueios de recursos, a menos que um processo do usuário seja encerrado. No que diz respeito a Javaapi, os impasses de threads podem ocorrer na seguinte situação.
11. O que é um fio faminto até a morte e o que é uma trava ao vivo?
Embora a fome de threads e os bloqueios da vida não sejam considerados problemas comuns, como impasse, eles são como um encontro para designers de programação simultânea.
Quando todos os threads são bloqueados ou não podem ser processados porque o recurso necessário é inválido, não há threads não bloqueadores para disponibilizar o recurso. Tópico Live Lives em Javaapi pode ocorrer nas seguintes situações:
As perguntas aqui não são detalhadas, espero que sejam úteis para todos. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a todos a tempo. Muito obrigado pelo seu apoio ao site wulin.com!