Em 2020 Java multithreading e séries simultâneas de perguntas da entrevista 22 de alta frequência (e respostas anexado analítica mapa mental)

prefácio

Agora não importa o quão empresa grande ou pequena, ir para a entrevista será solicitado ao conhecimento multi-threaded e concorrente programação, entrevistamos quando este conhecimento não se esqueça de reserva com bastante antecedência.

Sobre multithreading e conhecimento concorrência resumiu um mapa mental, para que todos possam compartilhar

v2-ff5061172a05e7f3b821b1f08b532a44_720w.jpeg

1, o Java multi-threaded Existem várias maneiras

herança da classe (1) da linha;

(2) aplicar Execut�el;

(3) implementar a interface mobilizável para criar rosca por invólucro rosca FutureTask;

(4) uso ExecutorService, mobilizável, Futuro já perceberam retorna o resultado de um multi-threaded (isto é, o uso de ExecutorService três formas de gerir a frente).

2, como parar um segmento em execução

(1) o uso de sinais de saída, as saídas de rosca normalmente, isto é, após a conclusão dos termina método de fibra de execução.

(2) Método usando uma parada forçosamente terminada, mas não recomenda este método, porque a parada método e suspender e retomar são os mesmos que o expirar.

(3) usando o método de rosca de interrupção de interrupção.

classe MyThread estende Thread { 
	parada booleana volátil = false; 
	public void run () { 
		enquanto {(stop!) 
			System.out.println (getName () + "está em execução"); 
			try { 
				sono (1000); 
			} 
			Catch (InterruptedException e) { 
				System.out.println ( "semana a partir blcok ..."); 
				parada = true; 
				//在异常处理代码中修改共享变量的状态
			} 
		} 
		System.out.println (getName () + "está saindo ..."); 
	}} class InterruptThreadDemo3 { 
	public static void main (String [] args) throws InterruptedException { 
		MyThread m1 = new MyThread (); 
		System.out.println ( "Iniciando fio ..."); 
		m1.start (); 
		Fio.
		m1.interrupt ();
		// estado de bloqueio obstrução Exit 
		Thread.sleep (3000); 
		interromper o thread principal para dormir // 3 segundos, a fim de observar o fio m1 
		System.out.println ( "Parando aplicação arquivo ..."); 
	}}

3, notificar () e notifyAll () Qual é a diferença?

notificar poderia levar a um impasse, mas não notifyAll

Toda vez que apenas um thread pode adquirir o bloqueio, o que significa que apenas um thread pode executar em usos de código sincronizadas notifyAll, pode acordar todos os segmentos em um estado de espera, ele re-entra na contenção de bloqueio da fila, e notificar apenas uma esteira.

wait () deve ser compatível com o uso do loop while não deve ser usado se, certifique-se de verificar todas as condições antes e depois da chamada wait (). Se não, você deve ligar para notificar () acorda outro segmento para lidar com a sua própria espera continuar () novamente até que estejam reunidas as condições execução para baixo.

notificar () é otimizada para uma notifyAll (), mas tem um cenários de aplicação muito precisas, e requer a utilização adequada. Caso contrário, pode levar a um impasse. WaitSet cena correta deve estar esperando nas mesmas condições, qualquer dos quais pode acordar a próxima questão de direito, se fio desperta não pode lidar corretamente, certifique-se de continuar a notificar () ao lado da linha, e retorno às suas próprias necessidades WaitSet no.

4, o sono () e wait () Qual é a diferença?

Para o método sleep (), primeiro precisamos de saber que pertence classe Thread. E wait () método, faz parte do objeto de classe

A.

sleep () método resulta em um programa de suspender o tempo especificado, de modo que o cpu dos outros tópicos, mas os seus restos mortais estavam monitorando estado, quando o tempo especificado é se retomará a operação automaticamente. Durante a chamada para o método sleep (), o fio não vai liberar o bloqueio objeto.

Quando a chamada de esperar () método, o fio vai desistir do bloqueio do objeto, na espera para este objeto para aguardar a piscina de bloqueio, somente após chamar notificar para este método de objeto () do fio antes de passar objeto pool bloqueio pronto para adquirir o bloqueio objeto em operação.

v2-0c087e22fca56285b587313521030a26_720w.png

5. Que volátil é provável? Assegura uma sex ordenada?

Uma vez que uma variável compartilhada (variáveis ​​membro da classe, a classe de variáveis ​​de membro estático) depois de ser declarado volátil, em seguida, ter as duas semântica:

(1) para assegurar visibilidade quando diferentes segmentos para esta operação variável, que é um fio modifica o valor de uma variável, este novo valor para outro segmento é imediatamente visível, palavra-chave volátil forçará valor alterações escrever memória principal imediatamente.

(2) proibir reordenação de instruções.

operações atômicas não são voláteis

Qual é a parte garantia da ordem?

Quando o programa é executado para ler ou gravar em uma variável volátil, a mudança na frente de toda a operação certamente tem, e os resultados já são visíveis na parte de trás da operação; operando por trás dele certamente não foi realizado;

x = 2; // declarações 1y = 0; // declarações 2flag = true; // declarações 3x = 4; // declarações 4y = -1; // declarações 5

Desde variáveis ​​ag fl variáveis ​​voláteis, então o processo de reordenamento é realizada na instrução, não coloque a instrução declaração 3 1, 2 na frente da declaração, a declaração não fala em 3 declaração 4, 5 atrás da declaração. Mas tenha cuidado sequência de declarações 1 e 2 da declaração, declarações sequenciais 4 e 5 da declaração não é nenhuma garantia.

assunto volátil usando estado de bloqueio duplo é geralmente usado e da quantidade de etiqueta padrão Singleton

6. Qual é a diferença classe Thread start () e o método run ()?

método start () é usado para iniciar um novo tópico é criado, eo start () internamente chama o método run (), e este efeito chamada diretamente método run () não é o mesmo. Quando você chamar o método run () só vai ser invocado no segmento original, nenhuma nova thread é iniciado, método start () vai iniciar um novo tópico.

7. Por que esperar, notificar e notifyAll estes métodos não são thread dentro da classe?

JAVA razão óbvia é a de proporcionar um nível de bloqueio do objecto em vez do nível de rosca, cada objecto tem uma fechadura obtido por um fio. Se um segmento precisa esperar por algum bloqueio em seguida, chamar o método do objeto wait () ao senso. Se o método wait () definido na classe Thread, qual segmento está aguardando o bloqueio não é óbvia. Basta colocar, porque a espera, notificar e notifyAll são operações de nível de bloqueio, de modo que eles são definidos na classe Object porque fechaduras pertencem ao objeto.

8. Por que esperar e notificar os métodos a serem invocadas em um bloco sincronizado?

(1) somente se o segmento de chamada tem um bloqueio exclusivo em um objeto para ser capaz de chamar espera do objeto (), notify () eo método notifyAll ().

(2) Se você não fizer isso, seu código irá lançar uma IllegalMonitorStateException exceção.

(3) Outra razão é para evitar condições de corrida entre a espera e notificar.

wait () método força a corrente de rosca libera o bloqueio objeto. Isso significa que antes de chamar o método de um objeto wait (), o segmento atual deve ter obtido um bloqueio do objeto. Portanto, antes de chamar rosca deve esperar método () do objecto no método de sincronização de um objecto ou bloco sincronizado de código.

método antes de chamar o objeto de notificar () e notifyAll (), o segmento de chamada deve ter sido um bloqueio para o objeto. Assim, deve notificar chamada para o método objecto () ou notifyAll () no método de sincronização de um objecto ou de blocos de código de sincronização.

A razão para o método de chamada wait () é geralmente o chamado fio desejo de continuar depois de um determinado estado (ou variável) está definido. A razão para chamada notificar () ou notifyAll () método é geralmente o segmento de chamada quer dizer aos outros esperando tópico: "estatuto especial tem sido set" Este estado, como canal de comunicação inter-thread, ele deve ser uma variável de estado comum (ou variáveis).

9, a diferença de Java interrompido e métodos isInterruptedd?

interrompida () e isInterrupted () A principal diferença entre o primeiro eo último vontade não de status de interrupção clara. Java mecanismo de interrupção multi-threaded é usado para obter a identificação interna, chamar Thread.interrupt () para interromper um fio vai definir o sinalizador de interrupção para verdadeira. Quando o segmento de interrupção chama o método estático Thread.interrupted () para verificar o status de interrupção, o status de interrupção é apagada. Em vez do método estático isInterrupted () para consultar o status de interrupção outros segmentos e status de interrupção não vai alterar o logotipo. Simplesmente significa que qualquer método irá lançar uma InterruptedException exceção de interrupção de status está desmarcada. Em qualquer caso, não há estado de interrupção de um segmento é susceptível de ser chamado por outras interrupções de rosca para mudar.

10, Java e sincronizado ReentrantLock Qual é a diferença?

semelhanças:

Ambos modo síncrono há muitas semelhanças, eles estão bloqueados modo síncrono, e estão a bloquear a sincronização, o que significa que, se uma thread quando o bloqueio do objeto para entrar no acesso de blocos de sincronização para os outros blocos de sincronização o custo de tópicos bloqueados deve esperar lá fora em blocos de sincronização, enquanto bloqueia threading e wake-up é relativamente alta.

diferença:

A maior diferença entre estes dois métodos é sincronizado, é a linguagem java palavra-chave, é o nível de sintaxe nativa exclusão mútua é necessário para alcançar JVM. E é ReentrantLock nível API fornecida mutex após 1,5 JDK, requer lock () e método de desbloqueio () com o try / finalmente bloco de instruções para completar.

Sincronizado sido a compilação, vai formar as instruções monitorenter e monitorexit antes e após os de dois bytes blocos de sincronismo de código, respectivamente. Na implementação de instrução monitorenter, devemos primeiro tentar obter o bloqueio objeto. Se o objeto não está bloqueado, ou o segmento atual já tem o bloqueio do objeto, a calculadora bloqueio mais 1, apropriado, na implementação de instrução monitorexit irá travar calculadora para menos 1, quando a calculadora é 00:00, bloqueio ele foi libertado. Se o bloqueio não consegue obter o objeto que o segmento atual irá bloquear até que o bloqueio objeto é liberado por outro segmento até agora.

Desde ReentrantLock um mutex está disponível no âmbito do pacote java.util.concurrent, em comparação com Sincronizado, classe ReentrantLock fornece algumas características avançadas, principalmente nas seguintes três:

(1) espera pode ser interrompido quando o fio segurando a liberação de bloqueio por longos períodos de segmentos de espera pode optar por desistir de espera, que é equivalente à situação sincronizada pode evitar impasse.

(2) fechaduras feira, vários segmentos de espera para o mesmo bloqueio, o bloqueio deve ser obtido de acordo com o bloqueio aplicação ordem cronológica, bloqueio sincronizado bloqueio injusto, construtor ReentrantLock padrão é criado bloqueio injusto pode ser configurado via o verdadeiro justo parâmetro bloquear, mas o desempenho desempenho justo bloqueio não é muito bom.

(3) se ligar a uma pluralidade de estado de bloqueio, o objecto pode ser ligado a um ReentrantLock objetos simultaneamente.

v2-68d41e0126eb04a454a9252ebc8dd613_720w.png

11, existem três linhas T1, T2, T3, como garantir a implementação da ordem?

Existem várias maneiras em linha vários segmentos para executar uma ordem específica, você pode começar outro segmento em um segmento com um método join () da classe Thread, outro segmento para completar o segmento continua. A fim de assegurar um ordenado três tópicos primeiro você deve começar passada (T3 chamada T2, T2 chamada T1), por isso vai ser concluída T1 e T3 finalizado.

Na verdade, a primeira de três fios início que ambos seguidos, porque cada thread no método de execução pelo método de definir a ordem de execução juntar três tópicos.

classe JoinTest2 {public 
	// 1. Há T1, T2, T3 três tópicos, após a implementação como para garantir a execução T2 T1, T3 executado após a execução T2 
	void main (String [] args) public static { 
		final do Tópico o fio novo new = t1 (o Runnable novo new () { 
			@Override 
			public void run () { 
				System.out.println ( "t1"); 
			} 
		} 
		); 
		@Override 
		public void run () { 
			try { 
				// referências fio t1, espera executar o segmento t1 
				t1.join (); 
			} 
			a captura (InterruptedException E) { 
				e.printStackTrace (); 
			} 
			System.out.printlnl ( "T2"); 
		} 
	} 
	); 
	o fio T3 = o segmento novo novo (a Execut�el novo novo () { 
		@Override 
		public void run () { 
			o try { 
				// referências t2 linha, um fio de execução espera t2 End 
				t2.join (); 
			} 
			a captura (InterruptedException E) { 
				e.printStackTrace (); 
			} 
			System.out.println ( "T3"); 
		} 
	} 
	); 
	T3. start (); 
	// aqui três tópicos começar a seqüência pode ser arbitrária, podemos tentar próxima! 
	t2.start (); 
	t1.start ();}}

12, SynchronizedMap e ConcurrentHashMap Qual é a diferença?

SynchronizedMap () e Hashtable, como implementado em todos os métodos ao chamar o mapa, o mapa inteiro estão sincronizados. A implementação de fechaduras ConcurrentHashMap mas mais preciso, seu mapa de todos os baldes adicionados. Enquanto há um fio para acessar o mapa, outros segmentos não pode entrar no mapa, e se um fio acessando ConcurrentHashMap o barril, outros segmentos ainda pode executar determinadas operações no mapa.

Assim, ConcurrentHashMap no desempenho e de segurança, significativamente maior do que Collections.synchronizedMap () é mais vantajoso. Ao mesmo tempo, a operação síncrona para controlar com precisão o balde, de modo que mesmo quando percorrendo o mapa, se outro tentativas de rosca para mapear modificação de dados, não vai jogar ConcurrentModi fi cationException.

13. Qual é thread-safe

Que o acesso multi-thread thread-safe o mesmo código, não produz resultados indeterminados.

Em um ambiente de vários segmentos, quando cada segmento não compartilhar os dados que são membros particulares (privados), então deve ser thread-safe. No entanto, esta situação é rara, necessidade de compartilhar dados, na maioria dos casos, quando é necessário para o controle de sincronização adequada.

Segmento de segurança geralmente envolvem sincronizada, é uma parte de código, ao mesmo tempo apenas uma rosca para manipular os resultados de outra forma pode gerar um processo intermediário pré-formado.

Se o seu código onde o processo tem múltiplas threads em execução ao mesmo tempo, e esses segmentos podem executar este código ao mesmo tempo. Se cada corrida ArrayList não é thread-safe.

14, método de rendimento da classe Thread em que papel?

Rendimento método para pausar o objeto thread atualmente em execução, deixar o outro tem o mesmo segmento prioridade. É um método estático e só garantir a thread atual não pode dar-se o uso da CPU para garantir que outros tópicos serão capazes de assumir a CPU, executar yield () rosca é susceptível de ser executado imediatamente após entrar no estado suspenso.

15. Qual é a diferença encadeamentos Java na piscina submit () e executar () método?

Ambos os métodos podem ser submetidos à tarefa pool de threads, tipo de retorno método execute () é nula, é definido na interface Executor, e submit () método retorna um objeto realizada por Future resultados de cálculo, que é definido na interface de ExecutorService, que estende a interface Executor, como o outro ThreadPoolExecutor pool de threads e ScheduledThreadPoolExecutor ter estes métodos.

16, para falar sobre a sua própria compreensão da palavra-chave sincronizado

A solução é sincronizado palavra-chave para acessar recursos entre a sincronização de threads múltiplos, palavra-chave sincronizado pode ser garantida pelo seu método ou bloco de código modificado a qualquer momento, apenas um thread de execução.

Além disso, no Java versões anteriores, o bloqueio pesado sincronizado pertence, ineficiente, uma vez que o bloqueio do monitor (monitor) é dependente do sistema operacional subjacente para alcançar Mutex Lock, encadeamentos Java são mapeados para threads nativas do sistema operacional diante. Para acordar um fio ou suspender, as necessidades do sistema operacional para ajudar a completar, a necessidade de converter a partir do modo usuário para modo kernel ao alternar entre tópicos operando implementação do sistema, a transição entre um estado requer um tempo relativamente longo, o custo do tempo relativamente alta, razão pela qual no início sincronizado razões de baixa eficiência. Felizmente, depois de funcionário de nível JVM Java 6 Java a partir da otimização sincronizado maior, então agora sincronizado eficiência bloqueio é otimizado muito bem. Fecho de bloqueio JDK1.6 conseguido introduzido um número de optimização, tais como bloqueio de rotação bloqueio de rotação adaptabilidade, para eliminar o bloqueio, o bloqueio rugosidade inclinado, de peso leve e outras técnicas para reduzir a sobrecarga de operações de bloqueio de bloqueio.

17, para falar sobre como ele está usando a palavra-chave sincronizado, usou o uso de palavras-chave sincronizada em três projetos principais:

(1) exemplo de modificação do método : a fechadura actua sobre a instância de objecto actual, antes de entrar o código de sincronização para obter a instância de bloqueio objecto actual

(2) modificar o método estático : isso é para bloquear a classe atual, será aplicada a todas as instâncias objeto da classe, porque os membros estáticos não pertencem a qualquer instância de um objeto, os membros de classe (estáticos indica que esta é uma classe de recurso estático, independentemente da quantos novos objetos, apenas um). Então, se um método thread A non-static sincronizado chama uma instância de um objeto, e as necessidades segmento B para chamar esse método estático sincronizada pertence à classe da instância do objeto, é permitido, exclusão mútua não vai acontecer, porque o acesso estática sincronizado bloqueio método é ocupada as fechaduras classe corrente, o acesso à fechadura método não-estático sincronizados é ocupado pelo exemplo actual da fechadura objecto.

(3) modificação de blocos de código : o objeto de bloqueio especificado, para bloquear um dado objecto, na biblioteca de código de sincronização para obter um bloqueio antes de um dado objecto.

Resumo : sincronizado chave estática adicionado a um método estático e sincronizado (classe) é o bloco de código é bloqueada para a classe Classe. Exemplos da palavra-chave sincronizados adicionada à instância de objecto está bloqueado. Tente não usar sincronizado (String a) porque a JVM, a piscina string constante tem uma função de cache!

18. O que é thread-safe? Vector é uma classe thread-safe fazer?

Se o seu código onde o processo tem múltiplas threads em execução ao mesmo tempo, e esses segmentos podem executar este código ao mesmo tempo. Se cada execução

As linhas de resultados e resultados operacionais single-threaded são os mesmos, e também os valores de outras variáveis ​​e as expectativas são as mesmas, isto é thread-safe.

19, o papel da palavra-chave volátil?

Uma vez por variáveis ​​compartilhadas voláteis modificados (variáveis ​​membro da classe, a classe de variáveis ​​de membro estático), em seguida, ter as duas línguas

Yi:

(1) para assegurar visibilidade quando diferentes segmentos para esta operação variável, que é um fio modifica o valor de uma variável, este novo valor para outro segmento é imediatamente visível.

(2) proibir reordenação de instruções.

(3) natureza volátil está contando os valores das variáveis ​​atuais JVM no registo (memória de trabalho) é incerta, precisa ser lido a partir da memória principal; sincronizado variável atual está bloqueado, apenas o segmento atual pode acessar as variáveis, outros segmentos ele bloqueou ao vivo.

(4) Nível volátil só pode ser utilizado em uma variável; as variáveis ​​sincronizados podem ser utilizados nos métodos, e o nível de classe.

(5) visibilidade volátil só pode ser conseguido modificar variáveis, não garante atomicidade; é garantido que modificar a visibilidade sincronizados e variáveis ​​atômicas.

(6) volátil não irá causar obstrução rosca; sincronizados podem causar obstrução rosca.

(7) não marcado compilador variável optimização volátil; marca pode ser sincronizado variável optimizar compilador.

v2-a2307d8f90ab3adac9c28fd2f2b0c37b_720w.png

20. O pool de threads comum?

(1) newSingleThreadExecutor: criar um pool de threads de single-threaded, este pool de threads para garantir que a ordem de execução de todas as tarefas apresentadas para a ordem das tarefas.

(2) newFixedThreadPool: para criar um pool de threads de tamanho fixo, cada commit uma tarefa para criar um fio, até que o thread do pool para atingir o tamanho máximo.

(3) newCachedThreadPool: Criando um pool de threads em cache, este pool de threads não restringir o tamanho do pool de threads, pool de threads tamanho máximo de segmento depende inteiramente do tamanho do sistema operacional (ou JVM) que pode ser criado.

(4) newScheduledThreadPool: Criar um tamanho ilimitado do pool de threads, pool de threads para apoiar esta demanda, bem como o calendário de tarefas periódicas.

(5) newSingleThreadExecutor: criar um conjunto de encadeamentos de single-threaded. Este pool de threads para apoiar o momento ea necessidade de executar tarefas periodicamente.

21, brevemente a sua compreensão do pool de threads

(Se você fizer a pergunta, você pode expandir o pool de threads Como falar sobre os benefícios do pool de threads, a política de inicialização pool de threads) uso racional do pool de threads pode trazer três benefícios.

(1) reduzir o consumo de recursos. Ao reutilizar o segmento foi criado para reduzir a criação de thread e destruição causada pelo consumo.

(2) aumentar a velocidade de resposta. Quando a missão chega, a tarefa pode não precisa esperar até a criação thread pode ser implementada imediatamente.

(3) aumentar a capacidade de gestão de discussão. Um fio é um recurso escasso, se a criação ilimitada, não só consome recursos do sistema, mas também reduzir a estabilidade do sistema, usando um pool de threads pode ser unificado distribuição, regulação e monitoramento.

22, o programa Java é como implementá-lo

Nossas ferramentas de desenvolvimento de uso de trabalho diário (IntelliJ IDEA ou Eclipse, etc.) pode facilmente depurar um programa, ou pela ferramenta para projeto embalados em frasco ou pacote guerra saco, e assim por diante para o recipiente Tomcat Web embalagem ser uma operação normal

(1) código é compilado pela primeira vez em código Java byte, ou seja, o tipo de arquivos .java compilados em tipo de arquivo .class. Substancialmente processo de execução do processo: código-fonte Java -> analisador léxico -> parser -> Semântica Analyzer -> gerador de código de caracteres -> última análise, gerar o código byte, qualquer falha fará com que o nó para executar uma falha de compilação ;

(2) para colocar os arquivos de classe para a máquina virtual Java, a máquina virtual geralmente se refere a própria oficial Hotspot JVM da Oracle;

(3) ficheiros de classe Java Virtual carregadora classe máquina (Classe Loader) carregado;

(4) Depois de se completar o carregador de classe, código de bytes vão eficácia, intérprete código de bytes de eficiência iria então JVM código byte em código de máquina, traduzindo teste referiu-se ao sistema operacional. Mas nem todo o código é interpretado, JVM otimizado para fazer isso, por exemplo, a máquina virtual Hotspot, ele próprio fornece JIT (Just In Time) é o que geralmente se referem ao compilador dinâmico, ele pode código de tempo de execução é compilado para hot spots código de máquina, desta vez implementação do compilador bytecode torna. programa Java fluxograma executado da seguinte forma:

v2-9a650ff4fae65b471efcb741a3138c5b_720w.jpeg

finalmente

Bem-vindo ao número preocupação pública: Programador Manada, receber fabricantes de primeira linha Java Interview Questions sumárias + pontos conhecimento aprendizagem Mente + um resumo conhecimentos documento pdf 300 núcleo Java!

Quando o conteúdo desses materiais são a entrevista, o entrevistador irá pedir pontos de conhecimento, pontos de capítulo, incluindo um monte de conhecimento, incluindo o conhecimento básico, coleções Java, JVM, princípio multi-threaded, primavera, micro-serviços, Netty e RPC, Kafka , diário, padrões de projeto, algoritmos Java, banco de dados, Zookeeper, caching distribuído, estruturas de dados, e assim por diante.



Acho que você gosta

Origin blog.51cto.com/14442094/2486138
Recomendado
Clasificación