Maison  >  Article  >  Java  >  Résumer et organiser les questions d'entretien du fil Java

Résumer et organiser les questions d'entretien du fil Java

WBOY
WBOYavant
2022-06-29 15:15:541571parcourir

Cet article vous apporte des connaissances pertinentes sur java, qui organise principalement des questions connexes sur les questions d'entretien de fil, y compris la différence entre les méthodes ordinaires modifiées synchronisées et les méthodes statiques, le principe de programmation sans verrouillage CAS, volatile et synchronisé. Quelles sont les différences et ainsi de suite ? Jetons-y un coup d'œil ci-dessous. J'espère que cela sera utile à tout le monde.

Résumer et organiser les questions d'entretien du fil Java

Étude recommandée : "Tutoriel vidéo Java"

1. Quelle est la différence entre les méthodes ordinaires modifiées synchronisées et les méthodes statiques ? Qu'est-ce que la visibilité ?

Les verrous d'objet sont utilisés pour les méthodes d'instance d'objet, ou une instance d'objet, et les verrous de classe sont utilisés pour les méthodes statiques d'une classe ou les objets de classe d'une classe. Nous savons qu'il peut y avoir plusieurs instances d'objet d'une classe, mais chaque classe n'a qu'un seul objet de classe, donc les verrous d'objet des différentes instances d'objet n'interfèrent pas les uns avec les autres, mais il n'y a qu'un seul verrou de classe pour chaque classe.
       Une chose à noter est qu'en fait, le verrouillage de classe n'est qu'une chose conceptuelle et n'existe pas réellement. Le verrouillage de classe verrouille réellement l'objet de classe correspondant à chaque classe. Les verrous de classe et les verrous d’objet n’interfèrent pas non plus les uns avec les autres.
La visibilité signifie que lorsque plusieurs threads accèdent à la même variable, si un thread modifie la valeur de la variable, les autres threads peuvent immédiatement voir la valeur modifiée.
Puisque toutes les opérations sur les variables par les threads doivent être effectuées dans la mémoire de travail et ne peuvent pas directement lire et écrire des variables dans la mémoire principale, alors pour les variables partagées V, elles sont d'abord dans leur propre mémoire de travail puis synchronisées avec la mémoire principale. Cependant, il ne sera pas vidé dans la mémoire principale à temps, mais il y aura un certain décalage horaire. Évidemment, à ce stade, l'opération du thread A sur la variable V n'est plus visible pour le thread B.
Pour résoudre le problème de visibilité des objets partagés, on peut utiliser le mot clé volatile ou le verrou.

2. Quelles sont les catégories de cadenas ?

Résumer et organiser les questions dentretien du fil Java

3. Le principe de la programmation sans verrouillage CAS.

                Les processeurs actuels supportent essentiellement l'instruction CAS(), mais les algorithmes implémentés par chaque fabricant sont différents. Chaque processus de fonctionnement CAS contient trois opérateurs : une adresse mémoire V, une valeur attendue A et une nouvelle valeur B. Pendant le fonctionnement, si le La valeur stockée à cette adresse est égale à la valeur attendue A, alors la valeur à l'adresse est affectée à la nouvelle valeur B, sinon aucune opération n'est effectuée.
L'idée de base de CAS est que si la valeur à cette adresse est égale à la valeur attendue, alors attribuez-lui une nouvelle valeur. Sinon, ne faites rien d'autre que renvoyer la valeur d'origine. Loop CAS consiste à effectuer en continu des opérations cas dans une boucle jusqu'à ce qu'elle réussisse. On peut également parler de trois problèmes majeurs avec CAS.

4. Principe de mise en œuvre de ReentrantLock.

Un thread peut entrer à plusieurs reprises dans n'importe quel bloc de code synchronisé avec un verrou qu'il possède déjà. Synchronized et ReentrantLock sont tous deux des verrous réentrants. En termes d'implémentation, chaque fois qu'un thread acquiert un verrou, il détermine si le thread qui acquiert le verrou est lui-même et accumule simplement le compteur. Chaque fois que le verrou est libéré, le compteur est décrémenté jusqu'à ce que la calculatrice revienne à zéro, indiquant que. le fil a été complètement libéré. La couche inférieure est implémentée à l'aide d'AQS dans JUC.

5. Principe AQS.

Il s'agit du framework de base utilisé pour créer des verrous ou d'autres composants de synchronisation. Par exemple, ReentrantLock, ReentrantReadWriteLock et CountDownLatch sont implémentés sur la base d'AQS. Il utilise une variable membre int pour représenter l'état de synchronisation et termine le travail de mise en file d'attente des threads d'acquisition de ressources via la file d'attente FIFO intégrée. Il s'agit d'une variante d'implémentation du verrou de file d'attente CLH. Il peut réaliser 2 méthodes de synchronisation : exclusive et partagée.
La principale façon d'utiliser AQS est l'héritage. Les sous-classes héritent d'AQS et implémentent ses méthodes abstraites pour gérer l'état de synchronisation. La conception du synchroniseur est basée sur le modèle de méthode modèle, donc si nous voulons implémenter notre propre classe d'outils de synchronisation, nous en avons besoin. pour couvrir plusieurs d'entre elles, telles que tryAcquire, tryReleaseShared, etc.
Le but de cette conception est que les composants de synchronisation (tels que les verrous) sont orientés utilisateur. Elle définit l'interface permettant aux utilisateurs d'interagir avec les composants de synchronisation (par exemple, en permettant à deux threads d'accéder en parallèle), en masquant les détails d'implémentation du synchroniseur ; est pour L'implémenteur de verrous simplifie la mise en œuvre des verrous et protège les opérations sous-jacentes telles que la gestion de l'état de synchronisation, la mise en file d'attente des threads, l'attente et le réveil. Cela isole efficacement les domaines sur lesquels les utilisateurs et les responsables de la mise en œuvre doivent se concentrer.
En interne, AQS maintient un état de ressource partagé et utilise le FIFO intégré pour terminer le travail de mise en file d'attente des threads d'acquisition de ressources. La file d'attente est composée de nœuds Node un par un. Chaque nœud Node conserve une référence précédente et une référence suivante, qui pointent respectivement vers ses propres nœuds prédécesseur et successeur, formant une liste doublement liée à deux extrémités.

6. Le principe de Synchronized et la différence avec ReentrantLock.

                  Principe synchronisé (ce) : implique deux instructions : Monitorenter, Monitorexit ; à en juger par les résultats de décompilation de la méthode de synchronisation, la synchronisation de la méthode n'est pas obtenue via les instructions Monitorenter et MonitorExit ; la méthode ordinaire, son Il existe un identifiant ACC_SYNCHRONIZED supplémentaire dans le pool de constantes.
La JVM implémente la synchronisation des méthodes basée sur cet identifiant : lorsque la méthode est appelée, l'instruction appelante vérifiera si l'indicateur d'accès ACC_SYNCHRONIZED de la méthode est défini. S'il est défini, le thread d'exécution obtiendra d'abord le moniteur, puis s'exécutera. une fois l'acquisition réussie. Corps de la méthode, le moniteur est libéré une fois la méthode exécutée. Lors de l'exécution de la méthode, aucun autre thread ne peut à nouveau obtenir le même objet moniteur.

7. Quelles optimisations Synchronized a-t-il effectuées ?

Introduction de technologies telles que le verrouillage rotatif, le verrouillage rotatif adaptatif, l'élimination du verrouillage, le grossissement du verrouillage, le verrouillage biaisé, le verrouillage léger, l'analyse d'échappement et d'autres technologies pour réduire le coût des opérations de verrouillage.

  • Escape Analysis : S'il est prouvé qu'un objet ne s'échappera pas de la méthode ou du thread, cette variable peut être optimisée :
  • Synchronization Elimination : élimination de la synchronisation, si un objet ne s'échappera pas du thread, alors les mesures de synchronisation pour cette variable peuvent être éliminées.
  • Élimination des verrous et élimination grossière des verrous : si le compilateur d'exécution de la machine virtuelle détecte qu'il est peu probable qu'une concurrence de données partagées se produise sur certains codes nécessitant une synchronisation au moment de l'exécution, il supprimera ces verrous.
  • Verrouillage grossier : fusionnez les blocs de code adjacents avec le même verrou. L'élimination de l'acquisition et de la libération inutiles de verrous peut améliorer les performances d'exécution du programme.

8. La différence et la portée des verrous statiques et non statiques synchronisés.

Les verrous d'objet sont utilisés pour les méthodes d'instance d'objet ou une instance d'objet, et les verrous de classe sont utilisés pour les méthodes statiques d'une classe ou les objets de classe d'une classe. Nous savons qu'il peut y avoir plusieurs instances d'objet d'une classe, mais chaque classe n'a qu'un seul objet de classe, donc les verrous d'objet des différentes instances d'objet n'interfèrent pas les uns avec les autres, mais il n'y a qu'un seul verrou de classe pour chaque classe.
       Une chose à noter est qu'en fait, le verrouillage de classe n'est qu'une chose conceptuelle et n'existe pas réellement. Le verrouillage de classe verrouille réellement l'objet de classe correspondant à chaque classe. Les verrous de classe et les verrous d’objet n’interfèrent pas non plus les uns avec les autres.

9. Volatil peut-il garantir la sécurité des fils ? Qu'est-ce que ça fait sur DCL ?

Il n'y a aucune garantie que le rôle de DCL soit : volatile assurera la visibilité et l'ordre des variables modifiées, garantissant qu'en mode singleton, l'ordre d'exécution lors de la création d'un objet doit être

  1. Allouer de l'espace mémoire
  2. instancier l'instance d'objet
  3. Pointez la référence de l'instance vers l'espace mémoire alloué À ce moment, l'instance a une adresse mémoire et n'est plus nulle, garantissant ainsi que l'instance est nulle ou a été. Objet complètement initialisé.

10. Quelle est la différence entre volatile et synchronisé ?

                    Volatile est le mécanisme de synchronisation le plus léger. Volatile garantit la visibilité lorsque différents threads opèrent sur cette variable. Autrement dit, si un thread modifie la valeur d'une variable, la nouvelle valeur est immédiatement visible par les autres threads. Cependant, volatile ne peut pas garantir l'atomicité des opérations, donc les opérations d'écriture composites sous multi-threads entraîneront des problèmes de sécurité des threads.
Le mot-clé synchronisé peut être utilisé pour modifier des méthodes ou sous forme de blocs synchronisés. Il garantit principalement que plusieurs threads ne peuvent avoir qu'un seul thread dans une méthode ou un bloc synchronisé en même temps. Il assure la visibilité de l'accès des threads aux variables. et exclusivité, également connu sous le nom de mécanismes de verrouillage intégrés.

11. Qu'est-ce qu'un thread démon ? Comment quitter un fil de discussion ?

Le thread Daemon est un thread de support car il est principalement utilisé pour la planification en arrière-plan et le travail de support dans le programme. Cela signifie que lorsqu'il n'y a aucun thread non démon dans une machine virtuelle Java, la machine virtuelle Java se ferme. Un thread peut être défini comme thread démon en appelant Thread.setDaemon (true). Nous ne l'utilisons généralement pas. Par exemple, le thread de récupération de place est le thread Daemon.止 L'arrêt du thread : soit l'exécution de RUN est terminée, soit une anomalie non traitée provoque la fin anticipée du thread. Les API correspondant au thread Thread pour suspendre, reprendre et arrêter les opérations sont suspend(), Ensure() et stop(). Mais ces API sont obsolètes, c’est-à-dire que leur utilisation n’est pas recommandée. Parce que cela entraînera le fonctionnement du programme dans un état incertain.其他 La suspension de la sécurité est que d'autres threads interrompent l'opération d'interruption en appelant la méthode interruption () d'un thread A, et le thread interrompu doit déterminer s'il est interrompu par le thread via le thread par la méthode Thread.interrupted(. ) est utilisé pour déterminer si le thread actuel est interrompu, mais Thread.interrupted() réécrira également le bit de l'indicateur d'interruption sur false.
12. La différence entre dormir, attendre et produire. Comment le fil d'attente le réveille-t-il ?
La méthode rendement() : fait que le thread actuel abandonne la propriété du processeur, mais le moment de l'abandon ne peut pas être défini. La ressource de verrouillage ne sera pas libérée. Tous les threads exécutant rendement() peuvent être à nouveau sélectionnés par le système d'exploitation et exécutés immédiatement après être entrés dans l'état prêt.

Après l'appel de rendement() et sleep(), le verrou détenu par le thread actuel ne sera pas libéré.

Après avoir appelé la méthode wait(), le verrou détenu par le thread actuel sera libéré, et une fois le thread actuel réveillé, il entrera à nouveau en compétition pour le verrou. Ce n'est qu'une fois le verrouillage terminé que le code suivant la méthode d'attente sera. exécuté.

Wait est généralement utilisé pour l'interaction entre les threads, sleep est généralement utilisé pour suspendre l'exécution et la méthode rendement() amène le thread actuel à abandonner la propriété du processeur.

Le fil d'attente utilise notify/notifyAll() pour se réveiller.

13. Le sommeil est-il interrompu ?

Sleep lui-même prend en charge les interruptions. Si le thread est interrompu pendant le sommeil, une exception d'interruption sera levée.

14. Cycle de vie du fil.

Le statut des threads en Java est divisé en 6 types :

Initial (NOUVEAU) : Un nouvel objet thread est créé, mais la méthode start() n'a pas encore été appelée.

Exécuter (RUNNABLE) : dans les threads Java, les deux états prêt et en cours d'exécution sont généralement appelés « en cours d'exécution ». Une fois l'objet thread créé, d'autres threads (tels que le thread principal) appellent la méthode start() de l'objet. Le thread dans cet état est situé dans le pool de threads exécutables, en attente d'être sélectionné par la planification des threads pour obtenir le droit d'utiliser le CPU. Il est actuellement dans l'état prêt. Le thread à l'état prêt passe à l'état d'exécution (running) après avoir obtenu la tranche de temps CPU.
  1. BLOQUÉ : Indique que le fil est bloqué dans le verrou.
  2. En attente : le thread entrant dans cet état doit attendre que d'autres threads effectuent des actions spécifiques (notification ou interruption).
  3. Timeout waiting (TIMED_WAITING) : Cet état est différent de WAITING, il peut revenir tout seul après le temps spécifié.
  4. TERMINATED : indique que le thread a terminé son exécution.
  5. 15. Qu'est-ce que ThreadLocal ?

           ThreadLocal est une variable spéciale en Java. ThreadLocal fournit une copie de la variable pour chaque thread, afin que chaque thread n'accède pas au même objet à un certain moment, isolant ainsi le partage de données par plusieurs threads.
    En termes d'implémentation interne, chaque thread contient un ThreadLocalMap, qui est utilisé pour enregistrer une copie des variables appartenant à chaque thread.

    16. Principes de base du pool de threads.

    Durant le processus de développement, l'utilisation rationnelle des pools de threads peut apporter 3 avantages.
    Premièrement : réduire la consommation de ressources.
    Deuxièmement : Améliorez la vitesse de réponse.
    Troisièmement : Améliorez la gestion des threads.

    1. Si le nombre de threads en cours d'exécution est inférieur à corePoolSize, créez un nouveau thread pour effectuer la tâche (notez que l'exécution de cette étape nécessite l'acquisition d'un verrou global).
    2. Si les threads en cours d'exécution sont égaux ou supérieurs à corePoolSize, ajoutez la tâche à BlockingQueue.
    3. Si la tâche ne peut pas être ajoutée à BlockingQueue (la file d'attente est pleine), un nouveau thread est créé pour traiter la tâche.
    4. Si la création d'un nouveau thread entraîne un dépassement du thread en cours d'exécution maximumPoolSize, la tâche sera rejetée et la méthode RejectedExecutionHandler.rejectedExecution() sera appelée.

    Dix-sept. Il existe trois threads T1, T2 et T3. Comment s'assurer qu'ils sont exécutés dans l'ordre ?

    Il peut être implémenté en utilisant la méthode join.

    Apprentissage recommandé : "Tutoriel vidéo Java"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer