« Projet de coeur » à venir à plus de 15 sujets confrontés à des questions une fois fraîche à la fin (1.1W mots de finition avec soin)

,

Cet article est pour ** « Collection proposée » 200Mo fabricants entretien de finition de documents examen d'entrevue fort sommaire en 2020 « chapitre CoreJava » ** écrire les réponses, tous les articles pertinents déjà inclus dans le code nuage dépôt: https://gitee.com / bingqilinpeishenme / Java entrevue

Plusieurs milliers d'eau aiment toujours voir le bien de louer, pour forcer l'Autriche

Cet article est une question d'entrevue de réponse multithread Partie I: Concepts de base + verrouillage de fil de pool de threads + les autres questions face seront écrites dans le prochain.

situation Partie:

  • Au total, 15 questions de visage
  • Illustrations, le concept de codes d'aide mutuelle +
  • Plus de 1.1W enfants de mots, il est recommandé de faciliter l'accès futur à la collecte

1. Quel est le processus? Qu'est-ce qu'un fil?

Processus (processus) et le fil (fil) est le concept de base du système d'exploitation, mais ils sont plus abstraits, pas facile à saisir.
Récemment vu une explication sur le blog Ruan Yifeng, je me sens très bien, à partager avec les petits partenaires.

  1. ** ordinateur central est CPU, il a pris toutes les tâches informatiques. ** Il est comme une usine, toujours en cours d'exécution.

  2. centrale électrique est limitée Assumed, il ne peut fournir un atelier. En d' autres termes, un atelier a commencé quand l'usine doit fermer l'autre. Signification est derrière cette une CPU unique ne peut exécuter qu'une seule tâche .

  3. Processus comme le plancher de l' usine, il représente une CPU unique peut gérer la tâche . A un moment donné , CPU toujours exécuter un processus, d' autres processus ne fonctionne pas.

  4. Un atelier, il y a beaucoup de travailleurs. Ils complètent une tâche collaborative

  5. Filiformes rapport des travailleurs dans l'atelier. Un procédé peut comprendre plusieurs threads .

processus

Le soi-disant processus est exécuté dans un système d'exploitation multi-tâches, le processus est une unité de planification des tâches de l'ordinateur, le système d'exploitation pour démarrer un programme dans le temps, va créer un processus, machine virtuelle Java est un processus. Entre le processus et le processus est isolé de l'autre, chaque processus a son propre espace de mémoire.

Les principes de la simultanéité d'ordinateur sont les suivantes: division de la tranche de temps CPU effectue alternativement, macro parallèle, micro série. De même, la séparation de l'unité de petites tâches est le fil sur la base du processus, notre multi-threading dite est un processus compliqué par plusieurs threads.

fil

Nous avons mentionné ci-dessus, un processus et peut émettre plusieurs threads, et le fil est la plus petite unité d'exécution des tâches, en particulier, l'exécution du processus d'une séquence de programme est un fil, notre principal est un fil rouge (le thread principal).

Composé de fils

Vous voulez avoir un fil, il est une partie intégrante de certains, il y a: une tranche de temps CPU, le stockage de données, le code.
Il y a une tranche de temps CPU, l'espace de stockage de données est ce que nous disons souvent que l'espace de tas et de l' espace pile alloué au système d'exploitation, entre les fils, l'espace tas est partagée par plusieurs threads, l' espace de pile est indépendante de l'autre, les avantages de le faire non seulement pratique, mais réduire aussi beaucoup de gaspillage des ressources. Code fait pas trop pour expliquer, pas de code Mao a présenté un multi-thread.

2. Qu'est-ce que la sécurité de fil?

A propos de ce qui est thread-safe, pourquoi est-il un fil de sécurité, et pourquoi vous avez besoin d'un verrou, je l'ai écrit une courte histoire en trois ou quatre ans.

Plusieurs petits concepts
de ressources critiques: Lorsque plusieurs threads accèdent au même objet, que l' on appelle les ressources essentielles
des opérations atomiques: une ressource intégrale en fonctionnement critique appelé atomique
thread-safe: plusieurs threads simultanément accès le même objet, pas détruit l' opération de segmentation, des incohérences de données peuvent se produire

fil « loi de la jungle » dans le monde

Bonjour à tous, je suis Wang marteau de forgeron, mon objectif est d'être le chef de la direction ... prendre la mauvaise quantité embarrassé le script. Bonjour à tous, mon nom est 0x7575, est un fil de ma ligne de vie est toujours idéale pour obtenir le processeur le plus rapide.

Donnez-vous sur le fil du monde, le fil du monde est un monde de la jungle, toujours des ressources rares, ce qui devrait saisir, que j'ai eu la chance d'obtenir quelques CPU nanosecondes, pour int a = 20 plus 1 opération une fois, quand je supprimer de la mémoire a, par incrémenter après avoir perdu la CPU, la mémoire après la pause prêt à écrire, je fus surpris de trouver: la mémoire d'un temps qui est devenu 22.

Il doit y avoir un fil en mon absence modifier les données, j'ai un dilemme, beaucoup de fils aussi essayé de me persuader de ne pas écrire, mais l'instruction forcée, je ne peux couvrir 21 dans la mémoire ne sont pas conformes à ma logique arithmétique 22.

Ce sont juste un petit accident, une chose semblable dans le monde après un autre fil, donc même si nous avons chacun un fil de diligence raisonnable, mais il semble que nous, les humains sont le coupable insécurisante de données.

Voici comment fait du tort ah, le monde a toujours été un fil monde compétitif, en particulier pour certaines variables partagées, des ressources partagées (ressources critiques), alors qu'il est normal lorsque plusieurs threads en compétition pour l'utilisation des choses. À moins d'éliminer les ressources partagées, mais cela est impossible, les choses ont commencé dans l'impasse.

Enfiler le monde semble un verrou

Heureusement, il reste des gens intelligents, on a pensé une bonne façon de résoudre le problème. Nous ne savons pas qui a pensé à la note, mais la note ne résout une partie du problème, la solution est de verrouillage .

Vous souhaitez définir un code de verrouillage pour le faire fonctionner? Si vous voulez aller prendre un verrou, puis obtenir le code de verrouillage peut être verrouillé faire ce qu'ils veulent, sinon obtenir la serrure, alors vous ne pouvez bloquer l'attente de la porte, parce que trop d'autres sujets, il a également est devenu un phénomène social (état), le phénomène social est nommé bloqué fil.

Cela paraît simple, mais en fait il y a beaucoup de dispositions détaillées de verrouillage, le gouvernement a publié les détails de « un certain nombre de dispositions synchronzied utilisation » et « un certain nombre de dispositions relatives à l'utilisation du Lock », puis relâché.

Entre les fils et les fils sont partagés mémoire, lorsque l'opération multi-thread sur la mémoire partagée a plusieurs problèmes sont inévitables, les conditions de course (condition de course) et la visibilité de la mémoire.
** Conditions de course: ** Lorsque plusieurs threads accèdent au même objet et la durée de fonctionnement des résultats finaux et le calendrier lié à la mise en œuvre de la décision correcte est pas en mesure de contrôle humain, peut être droit ou peut - être incorrect. ( A titre d'exemple)

Prenant la parole au-dessus de la serrure est de résoudre ce problème, des solutions communes sont les suivantes:

  • Utilisez le mot-clé synchronisé
  • Utilisez le verrouillage explicite (Lock)
  • Avec des variables atomiques

** Visibilité mémoire: ** sur les problèmes de visibilité de la première mémoire avec la mémoire et de parler de cpu à propos, est une mémoire matérielle, la vitesse d'exécution est des centaines de fois plus lent que le CPU, donc dans l'ordinateur, lorsque l'opération est effectuée dans la CPU, et les opérations de mémoire ne sont pas effectuées à chaque échange de données de temps, mais le premier processeur d'écrire des données dans la mémoire tampon (registre et niveaux de cache) est écrite dans la mémoire à la fin. Ce processus est le rapide, un seul thread et sans aucun problème.

Mais dans un multithread il y a un problème, un fil d'une mémoire de données modifié, mais n'a pas immédiatement écrit à la mémoire (temporairement stockées dans le cache), cette fois un autre thread des mêmes données pour apporter des changements temps pour que la mémoire n'a pas été données modifiées, qui est un fil pour modifier une variable partagée, et un autre thread ne peut pas être vu tout de suite, et même ne jamais voir.

Ceci est la visibilité du problème de la mémoire.

Une solution commune à ce problème est le suivant:

  • Utilisez le mot-clé volatile
  • Utiliser le mot clé ou la synchronisation synchronisé de verrouillage explicite

3. Quels sont l'état du fil?

Un fil ne s'exécute pas immédiatement après le début, mais dans un état prêt (prêt) , l'état prêt est une sorte d'état du fil, le fil est dans ce moyen d'Etat que tout est prêt, en attendant que le système d'allouer des tranches de temps. Pourquoi ne pas exécuté immédiatement, car en même temps qu'un seul thread peut obtenir une tranche de temps pour courir, lancer un nouveau thread quand il commence fil (le thread principal) est en cours d' exécution, le seul autre extrémité du fil principal, il est une chance d'obtenir une tranche de temps courir.

** état du fil: état initial ** (Nouveau), Prêt (Ready), état de fonctionnement (Running) (Note spéciale: Dans la définition de la grammaire, l'état de prêt et l'exécution est un état runable), état d'attente (Waitering ), l'état de terminaison (terminaison)

  1. L'état initial (Nouveau)
    1. objet thread est créé, est l'état initial, cette fois l'objet thread est juste un objet ordinaire, pas un fil
  2. runable
    1. ** état prêt (Prêt): début ** après avoir effectué la méthode, l'état prêt, en attendant d'être affecté à la tranche horaire.
    2. ** état de marche (marche): threads CPU ** pour commencer. Le fil est la durée de fonctionnement de la CPU n'est pas prise permanente jusqu'à la fin de la course, il peut ne pas avoir terminé la tranche de temps arrive à expiration, ils ont été privés du droit d'utiliser le CPU, et sera dans un état d'attente.
  3. état d'attente (en attente)
    1. état d'attente est divisé en attente limitée dans le temps et attendre indéfiniment, en attendant que l'initiative dite limitée dans le temps est le fil conducteur va dormir en utilisant la méthode du sommeil, il y a une certaine limite de temps, puis entrez le délai expire prêt, en attendant une nouvelle fois été CPU sélectionnée.
    2. Et attendre indéfiniment peu différent, ne pas indéfiniment moyen d'attente pour toujours aller plus loin, mais sans limite de temps, après une seconde peut aussi être beaucoup de secondes. Pour des raisons pas la même entrer dans l'attente, peut-être parce que la tranche de temps CPU expire, il peut être une opération de temps car (une base de données), ou appel actif méthode join.
  4. Bloqué (bloqué)
    1. état de blocage est en fait un état spécial d'attente, d'autres threads dans un état d'attente est en attente d'un autre thread pour effectuer la fin, en attendant d'obtenir le droit d'utiliser le CPU et le fil est bloqué en attente de plus que la CPU le droit à l'utilisation, marque principalement serrure, n'a pas obtenu la serrure jeton, même si le CPU est libre, il n'y a aucun moyen d'effectuer.
  5. Terminate le fil (Terminated)
    1. Le fil a été mis fin dans les Etats.

4. distinction d'attente du sommeil et

5. différence d'attente et d'obstruction

6. Java création de fil de la manière

  1. Discussion Héritage
  2. Mettre en œuvre Runnable
  3. Mettre en œuvre l'interface externe, et utiliser FutureTask
  4. Utilisez le pool de threads
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

public class NewThreadDemo {

    public static void main(String[] args) throws Exception {
        
        //第一种方式
        Thread t1 = new Thread(){
            @Override
            public void run() {
                System.out.println("第1种方式:new Thread 1");
            }
        };
        t1.start();
        
        TimeUnit.SECONDS.sleep(1);
        
        //第二种方式
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("第2种方式:new Thread 2");
            }
        });
        t2.start();

        TimeUnit.SECONDS.sleep(1);
        
        
        //第三种方式
        FutureTask<String> ft = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                String result = "第3种方式:new Thread 3";
                return result;
            }
        });
        Thread t3 = new Thread(ft);
        t3.start();
        
        // 线程执行完,才会执行get(),所以FutureTask也可以用于闭锁
        String result = ft.get();
        System.out.println(result);
        
        TimeUnit.SECONDS.sleep(1);
        
         //第四种方式
        ExecutorService pool = Executors.newFixedThreadPool(5);

        Future<String> future = pool.submit(new Callable<String>(){
            @Override
            public String call() throws Exception {
                String result = "第4种方式:new Thread 4";
                return result;
            }
        });

        pool.shutdown();
        System.out.println(future.get());
    }
}

7. appelable et Runnable de différence?

	class c implements Callable<String>{
		@Override
		public String call() throws Exception {
			return null;
		}
	}
	
	class r implements Runnable{
		@Override
		public void run() {
		}
	}

Le même point:

  1. sont toutes deux interfaces
  2. Les deux doivent commencer à appeler fil Thread.start

différences:

  1. Comme le montre le code ci-dessus, le procédé d'appel appelable noyau, ce qui permet la valeur de retour, le procédé de fonctionnement du noyau est exécutable, aucune valeur de retour
  2. méthode d'appel peut lancer une exception, mais la méthode d'exécution ne fonctionne pas
  3. Parce que runnable est Java1.1 là, il est retourné des valeurs n'existent pas, ce dernier a été optimisé java1.5, il y a eu appelable, ont une valeur de retour et Lancers
  4. et runnable appelable peut être appliqué à des exécuteurs. La classe prend en charge les fils ne runnable

8. Quelle est la piscine de fil? Quels sont les avantages?

Prenant la parole pool de threads pensera la technologie du réservoir, l'idée de base est l'une des plus précieuses ressources dans un étang, chaque utilisation pour obtenir de l'intérieur, puis exécutez dans la piscine pour une utilisation par d'autres, un peu manger désordre ce qui signifie.

Java pool de threads présente les avantages suivants:

  1. Un fil est une ressource rare, pas souvent créé.
  2. Découplage effet, pour créer un fil complètement séparé pour effectuer un entretien facile.
  3. Devrait le mettre dans un étang, peut être multiplexé à d'autres tâches.

9. Créer un mode de pool de threads

  1. Par classe Huissiers
  2. ThreadPoolExecutor par catégorie

En Java, nous pouvons créer un pool de threads par classe Exécuteurs , API commune sont:

  1. Executors.newCachedThreadPool (): illimité pool de threads.
  2. Executors.newFixedThreadPool (nThreads): créer un pool de threads de taille fixe.
  3. Executors.newSingleThreadExecutor (): Créer un seul thread pool de threads.
  4. Executors.newScheduledThreadPool ()
  5. Executors.newWorkStealingPool (int) java8 ajouté, en utilisant les processeurs actuellement disponibles sur le parallélisme au niveau de la machine comme

La méthode ci-dessus de la création d'un pool de threads, en fait, nous a donné JDK écrit, peut être utilisé pour prêt à l'emploi. Mais aussi longtemps que nous considérons le code source des méthodes ci-dessus, vous trouverez:

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

En utilisant les méthodes ci-dessus sont en fait des cours ThreadPoolExecutor.

Ainsi, la seconde façon est de créer un fil pour créer leur propre grâce à de nouveaux ThreadPoolExecutor.

10. Huissiers Il y a tellement de façons de créer un pool de threads, avec le développement de ce qui est mieux?

La réponse: un non.

De « Manuel Ali Baba Java Development » peut être vu

Pour une explication détaillée des paramètres voir la question suivante.

11. Comment un pool de threads personnalisé par ThreadPoolExecutor? C'est ce qui est important pool de threads de paramètre il?

Dans le dernier numéro, nous avons mentionné un pool de threads qui crée de nouveaux ThreadPoolExecutor le chemin à travers, puis, comment le créer? Au moment de la création, dont ils ont besoin des paramètres il?

Nous examinons la méthode de construction de ThreadPoolExecutor source directe, comme suit:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

Les paramètres sont denses, donc ce sont ces arguments?

Le processus est généralement

  1. Après avoir créé un pool de threads, a pour mission de soumettre au pool de threads, il commencera par la mise en œuvre du fil de base
  2. Si la tâche continue d'augmenter, corePoolSize Courez la file d'attente des tâches est pleine, et cette fois le pool de threads augmentera le nombre de threads, pour augmenter le nombre maximum de fils
  3. Si la tâche continue d'augmenter à ce moment, en raison du nombre de fils qui ont atteint le nombre maximal de threads, file d'attente est aussi plein, et cette fois le pool de threads est en fait pas la capacité d'effectuer de nouvelles tâches, il refusera d'adopter des politiques
  4. Si la tâche est diminuée, il y aura beaucoup de discussions ne sont pas nécessaires, rien faire, aussi longtemps que ces fils inactif pendant plus que le temps de fil de repos, sera détruit, jusqu'à ce que quelques autres fils corePoolSize.

Par les paramètres ci-dessus peut être fourni un pool de fil flexible, le code exemple suivant:

/**
* 获取cpu核心数
*/
 private static int corePoolSize = Runtime.getRuntime().availableProcessors();

    /**
     * corePoolSize用于指定核心线程数量
     * maximumPoolSize指定最大线程数
     * keepAliveTime和TimeUnit指定线程空闲后的最大存活时间
     */
    public static ThreadPoolExecutor executor  = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(1000));

12. Les travaux de la piscine de fil rouge?

A propos de principe de fonctionnement et pool de threads de processus de mise en œuvre pour montrer deux graphiques

  1. Après avoir créé un pool de threads, la tâche d'attente pour les demandes présentées plus.
  2. Lorsque vous appelez la méthode d'exécution () pour ajouter une demande de tâche, le pool de threads fera le jugement suivant:
    1. Si le nombre de threads en cours d'exécution inférieur à corePoolSize, puis créer immédiatement un thread est créé pour exécuter cette tâche immédiatement.
    2. Si le nombre de threads en cours d' exécution est supérieur ou égal à corePoolSize, cette tâche dans la file d' attente .
    3. Si le nombre de threads lorsque la file d'attente est pleine et en cours d'exécution est inférieur à maximumPoolSize, il doit encore créer un thread non-core pour exécuter cette tâche immédiatement.
    4. Si la file d' attente est pleine de fils nombre supérieur ou égal maximumPoolSize et en cours d' exécution, le pool de threads commence la saturation de déchets pour exécuter la stratégie .
  3. Quand un thread pour terminer la tâche, il sera retiré de la file d'attente une tâche à accomplir.
  4. Quand un thread est rien de plus qu'une certaine période de temps (keepAlilveTime), le pool de threads sera juger:
    1. Si le numéro du fil est en cours d'exécution plus corePoolSize, le fil est arrêté.
    2. Ainsi , après toutes les tâches de la piscine complète du fil , il finira par se réduire à la taille de corePoolSize .

13. La stratégie de saturation pool de threads de conversation, aussi appelé une stratégie de déni.

La stratégie dite de saturation est: Lorsque la file d'attente est déjà pleine, n'a jamais fait moins d'une nouvelle tâche, puis, le nombre maximum de threads dans le pool de threads est également au maximum, moyenne que le pool de threads n'a pas la capacité de continuer à accomplir de nouvelles tâches, et cette fois-ci aucune nouvelle demande d'emploi à la piscine de fil, comment traiter, est la stratégie de saturation (déni)

14. Comment l'allocation rationnelle d'un pool de threads

En général, nous devons déterminer la nature de l'exécution de ces tâches.

  • tâches IO-intensives: Comme le fil est toujours en cours d'exécution ne, de sorte que vous pouvez configurer le fil autant que possible, comme le nombre de CPU * 2
    • IO-intensive, qui est, la tâche nécessite beaucoup d'IO, qui est beaucoup de congestion.
    • IO-tâches en cours d'exécution intensifs sur un seul thread conduira à perdre beaucoup de puissance CPU gaspillée en attente.
    • Ainsi, les tâches IO-intensive à l'aide de plusieurs threads peuvent grandement accélérer le programme à exécuter, même sur un processeur single-core, cette accélération est principalement l'utilisation du temps de blocage est gaspillée.
  • CPU tâches intensives (un grand nombre d'opérations de complexes) devraient être allouées moins de threads, tels que le nombre correspondant à la taille de la CPU. des moyens de CPU à forte intensité que la tâche exige beaucoup de calcul, sans obstruction, fonctionne CPU à pleine vitesse.

Bien sûr, ce sont l'expérience, la meilleure façon est la configuration de test optimale en fonction de la situation réelle.

15. Comment fermer la piscine de fil

Fermer la piscine de fil a deux méthodes: shutdown()/shutdownNow().

  • shutdown() Après avoir effectué cesser d'accepter de nouvelles tâches, la tâche file d'attente d'exécution se terminera.
  • shutdownNow() Aussi a cessé d'accepter de nouvelles tâches, mais il interrompt toute tâche, l'état de pool de threads pour arrêter.

Fermez le pool de threads de code:

long start = System.currentTimeMillis();
for (int i = 0; i <= 5; i++) {
    pool.execute(new Job());
}
pool.shutdown();
while (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
    LOGGER.info("线程还在执行。。。");
}
long end = System.currentTimeMillis();
LOGGER.info("一共处理了【{}】", (end - start));

pool.awaitTermination(1, TimeUnit.SECONDS)Sera inspecté une fois par seconde si l'exécution est terminée (état TERMINATED), lorsque vous quittez la boucle while pour montrer que le pool de threads a été complètement terminé.

références:

  1. Une explication simple des processus et des fils
  2. Java- multithreading Basics
  3. Enfilez Synchronisation java-
  4. Quatre façons de créer un fil
  5. Appelable et Runnable de différence
  6. Élégant et comprendre comment utiliser la piscine de fil
  7. "Manuel Ali Baba Java Development"
  8. compréhension approfondie des principes des documents de pool de threads

Je salue le numéro de préoccupations du public: les notes de cerfs professeur Java, la technologie Java sera un des didacticiels graphiques de mise à jour à long terme et des didacticiels vidéo, Java expérience d'apprentissage, l'expérience d'entrevue Java et l'expérience pratique du développement en Java.

Je suppose que tu aimes

Origine www.cnblogs.com/bingyang-py/p/12557507.html
conseillé
Classement