De nombreuses questions d'entrevue de base Java proviennent des cadres multi-threading et de collections. Une expérience pratique compétente est nécessaire lors de la compréhension du concept de threads de base. Cet article recueille des questions typiques sur le filetage Java, qui sont souvent posées par des ingénieurs seniors.
0. Qu'est-ce que la synchronisation multithread en Java?
Dans le cadre de programmes multi-thread, la synchronisation peut contrôler l'accès aux ressources partagées. S'il n'y a pas de synchronisation, lorsqu'un thread Java modifie une variable partagée, un autre thread utilise ou met à jour la même variable, ce qui peut facilement conduire à des résultats incorrects dans le programme.
1. Expliquez plusieurs façons de mettre en œuvre le multi-threading?
Un thread Java peut implémenter l'interface Runnable ou hériter de la classe de threads pour l'implémenter. Lorsque vous prévoyez de hériter plusieurs fois, vous préférerez implémenter Runnable.
2. Quelle est la différence entre thread.start () et thread.run ()?
La méthode thread.start () (native) démarre le thread et entre dans l'état prêt. Lorsque le CPU alloue le temps au thread, le JVM planifie pour exécuter la méthode run ().
3. Pourquoi avons-nous besoin des méthodes run () et start ()? Pouvons-nous simplement utiliser la méthode run () pour terminer la tâche?
Nous avons besoin des deux méthodes de run () & start () car le JVM crée un thread séparé différent de l'appel des méthodes ordinaires, donc ce travail est effectué par la méthode de démarrage du thread. Le démarrage est implémenté par la méthode locale et doit être appelé affligeable. Un autre avantage de l'utilisation de ces deux méthodes est que tout objet peut être exécuté en tant que thread. Tant que l'interface Runnable est implémentée, cela évite les multiples problèmes d'héritage de Java causés par l'héritage de la classe de threads.
4. Quelle est la classe threadlocal et comment l'utiliser?
ThreadLocal est une variable locale au niveau du thread, pas un "thread local". ThreadLocal fournit une copie indépendante de la variable pour chaque thread qui utilise la variable. Chaque thread n'affecte pas la copie d'autres objets de thread lors de la modification de la copie (note du traducteur).
Voici les points clés des variables locales de threads:
Une variable locale de thread (variable threadLocal) fournit facilement une variable distincte pour chaque thread.
Les instances threadlocal apparaissent généralement dans une classe en tant que champs statiques privés (statiques privés), qui sont utilisés pour associer un fil.
Lorsque plusieurs threads accèdent aux instances ThreadLocal, chaque thread conserve une copie indépendante des variables fournies par ThreadLocal.
Les utilisations couramment utilisées peuvent être vues en mode DAO. Lorsque la classe DAO est une classe singleton, la connexion de la base de données est maintenue indépendamment par chaque thread et ne se affecte pas mutuellement. (Singleton basé sur le thread)
5. Quand l'invalidMonitorstateException sera-t-elle lancée et pourquoi?
Lorsque vous appelez l'une des méthodes en attente () / notify () / notifyall (), si le thread actuel n'obtient pas le verrouillage de l'objet, une exception d'IllegalMonitorStateException sera lancée (c'est-à-dire que le programme n'exécute aucun bloc de synchronisation ou de synchronisation de l'objet de l'objet. Étant donné que l'exception est une sous-classe de RuntimeExcpetion, l'exception ne doit pas être capturée (bien que vous puissiez l'attraper aussi longtemps que vous le souhaitez). En tant que runtimeException, ces exceptions ne sont pas mentionnées dans la signature de la méthode attend (), notify (), notifyall ().
6. Quelle est la différence entre le sommeil (), la suspension () et l'attente ()?
Thread.Sleep () fait le fil actuel dans un état "non exécutable" à l'heure spécifiée. Le thread contient toujours le moniteur de l'objet. Par exemple, si un thread est actuellement dans un bloc de synchronisation ou une méthode de synchronisation, d'autres threads ne peuvent pas entrer le bloc ou la méthode. Si un autre thread appelle la méthode Interrupt (), il réveillera ce fil de "sommeil".
Remarque: Sleep () est une méthode statique. Cela signifie qu'il n'est valable que pour le thread actuel, et une erreur commune est d'appeler T.Sleep () (ici, c'est un thread différent du thread actuel). Même si T.Sleep () est exécuté, le fil actuel va dormir, pas le fil T. T.SUSPEND () est une méthode obsolète. L'utilisation de suspendre () fait entrer le fil dans un état stagnant. Le thread conservera toujours le moniteur de l'objet, et Suspender () est susceptible de causer des problèmes de blocage.
Object.Wait () fait sortir le fil actuel d'un état "inactif". Contrairement à Sleep (), l'attente est une méthode d'objet plutôt que le thread. Lors de l'appel Object.Wait (), le thread doit d'abord obtenir le verrouillage de l'objet de cet objet. Le thread actuel doit garder l'objet de verrouillage synchronisé et ajouter le thread actuel à la file d'attente d'attente. Ensuite, un autre thread peut synchroniser le même verrou d'objet pour appeler object.notify (), qui réveillera le fil qui attendait à l'origine, puis relâchera le verrou. Fondamentalement, attendre () / notify () est similaire à Sleep () / Interrupt (), sauf que le premier nécessite l'acquisition de la serrure d'objet.
7. Que se passe-t-il lors de l'utilisation de la synchronisation sur les méthodes statiques?
Lors de la synchronisation d'une méthode statique, l'objet "classe" de la classe sera obtenu. Par conséquent, lorsqu'un thread entre dans une méthode statique synchronisée, le moniteur de thread acquiert le verrouillage de l'objet de la classe elle-même et d'autres threads ne peuvent saisir aucune méthode de synchronisation statique de cette classe. Ce n'est pas comme une méthode d'instance, car plusieurs threads peuvent accéder à différentes instances de méthodes d'instance synchrones simultanément.
8. Lorsqu'une méthode de synchronisation a été exécutée, le thread peut-il appeler la méthode d'instance asynchrone sur l'objet?
Oui, une méthode asynchrone peut toujours être appelée sans aucun problème. En fait, Java ne fait aucune vérification des méthodes asynchrones, et les objets de verrouillage ne sont vérifiés que dans les méthodes de synchronisation ou les blocs de code synchrones. Si une méthode n'est pas déclarée synchrone, même si vous utilisez des données partagées, Java l'appellera toujours sans vérifier s'il est sûr, alors soyez particulièrement prudent dans ce cas. La question de savoir si une méthode est déclarée synchrone dépend de l'accès à la section critique. Si la méthode n'accède pas à la section critique (ressources partagées ou structures de données), il n'est pas nécessaire de déclarer synchrone.
Voici un exemple: Common Class a deux méthodes synchronisésMethod1 () et Method1 (), et la classe Mythread appelle ces deux méthodes dans un thread indépendant.
classe publique Common {public synchronisé void synchroniséMethod1 () {System.out.println ("SynchronizedMethod1 appelé"); essayez {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("SynchronizedMethod1 Done"); } public void method1 () {System.out.println ("Méthode 1 appelé"); essayez {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("Method 1 Done"); }} La classe publique Mythread étend Thread {private int id = 0; Common privé commun commun; public myThread (String Name, int no, objet commun) {super (name); commun = objet; id = non; } public void run () {System.out.println ("Running Thread" + this.getName ()); essayez {if (id == 0) {Common.SynchronizedMethod1 (); } else {Common.Method1 (); }} catch (exception e) {e.printStackTrace (); }} public static void main (String [] args) {commun c = new Common (); Mythread t1 = new mythread ("mythread-1", 0, c); Mythread t2 = new mythread ("mythread-2", 1, c); t1.start (); t2.start (); }}Voici la sortie du programme:
Exécution de threadmythread-1
synchronisémethod1 appelé
Exécution de threadmythread-2
Méthode 1 appelée
SynchronizedMethod1 fait
Méthode 1 réalisée
Les résultats montrent que même si la méthode synchroniséeMethod1 () est exécutée, la méthode1 () sera appelée.
9. Les deux threads peuvent-ils appeler deux méthodes d'instance synchrones différentes sur un objet?
Non, parce qu'un objet a synchronisé la méthode d'instance, le thread acquiert le verrouillage de l'objet de l'objet. Par conséquent, d'autres méthodes de synchronisation ne peuvent être exécutées qu'après la libération de la méthode après la libération du verrouillage de l'objet. L'exemple de code suivant est très clair: la classe commune a synchroniséMethod1 () et SynchronizedMethod2 (), et Mythread appelle ces deux méthodes.
classe publique Common {public synchronisé void synchroniséMethod1 () {System.out.println ("SynchronizedMethod1 appelé"); essayez {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("SynchronizedMethod1 Done"); } public synchronisé void synchroniséMethod2 () {System.out.println ("SynchronizedMethod2 appelé"); essayez {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("SynchronizedMethod2 Done"); }} La classe publique Mythread étend Thread {private int id = 0; Common privé commun commun; public myThread (String Name, int no, objet commun) {super (name); commun = objet; id = non; } public void run () {System.out.println ("Running Thread" + this.getName ()); essayez {if (id == 0) {Common.SynchronizedMethod1 (); } else {Common.SynchronizedMethod2 (); }} catch (exception e) {e.printStackTrace (); }} public static void main (String [] args) {commun c = new Common (); Mythread t1 = new mythread ("mythread-1", 0, c); Mythread t2 = new mythread ("mythread-2", 1, c); t1.start (); t2.start (); }}10. Qu'est-ce qu'une impasse
Une impasse signifie que deux fils ou plus sont bloqués infiniment et que les threads s'attendent les uns aux autres pour les ressources requises. Cela peut se produire lorsque deux threads tentent d'acquérir des verrous pour d'autres ressources, et chaque thread attend indéfiniment la libération d'autres verrous de ressources à moins qu'un processus utilisateur ne soit terminé. En ce qui concerne Javaapi, des impasses de fil peuvent survenir dans la situation suivante.
11. Qu'est-ce qu'un fil affamé à mort et qu'est-ce qu'une serrure en direct?
Bien que la famine de fil et les verrous de la vie ne soient pas considérés comme des problèmes communs comme des blocs de blocage, ils sont comme une rencontre pour les concepteurs de programmation simultanée.
Lorsque tous les threads sont bloqués ou ne peuvent pas être traités car la ressource requise n'est pas valide, il n'y a pas de threads non bloquants pour rendre la ressource disponible. Des serrures en direct en fil à Javaapi peuvent se produire dans les situations suivantes:
Les questions ici ne sont pas détaillées, j'espère qu'elles seront utiles à tout le monde. Si vous avez des questions, veuillez me laisser un message et l'éditeur répondra à tout le monde à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!