Enfin bien comprendre! Une compréhension graphique de cas Java multi-thread des producteurs et des consommateurs de modèles de conception

Avant de suggestions de lecture

Si le papier doit avoir une compréhension plus profonde des recommandations regard thread-safe, fil interblocages et la communication des connaissances fil connexes, si vous avez déjà une connaissance suffisante de ceux-ci, je crois que vous devez lire ce blog gratifiant!

compréhension de la profondeur de threads Java - Les banques me doivent de quatre millions! ! !

Une minute illustration de l'impasse de fil Java avec une histoire de coucher

Tout d'abord, la scène du design

 Existant deux fils, le fil est à effet chaîne de caractères « A » « B » « C » « D » « E » ou « F » « G » « H » « I » « J » dans le récipient Array List ( ), mais afin d'assurer la sécurité du fil, vous ne pouvez faire un accès fil, de sorte que chaque fil doit acquérir le verrou de l'objet ressource critique qui est étiqueté conteneur pour accéder à l'objet, puis effectuer des opérations de stockage de données,
 mais, chaque fil de chaque cinq fois le nombre de caractères stockés, et le conteneur ne peut être stocké dans quatre cordes, lorsque le cinquième fil de chaîne dans le récipient, pour éviter des procédures anormales, le fil attendra indéfiniment dans la file d' attente, et notifier à l'accès aux consommateurs de données; de
 même, une pluralité de consommateurs, mais aussi avoir accès à des données se qualifient marque de verrouillage, en supposant un consommateur consumer, l' accès aux données des consommateurs, prend une hypothèse, lorsque le récipient lorsque les données ont été prises afin d'assurer le fil de sécurité, le fil attendra indéfiniment dans la file d' attente, et informer le producteur des données stockées,
Insérer ici l'image Description
 le processus est des modèles de conception de fil java entre les producteurs et les consommateurs;

En second lieu, l'introduction des producteurs et des consommateurs

 Vous devez d'abord comprendre la nature des producteurs et les consommateurs du fil, un certain nombre de producteurs dans la production de produits qui seront disponibles pour prendre un certain nombre de dépenses de consommation, afin de rendre les producteurs et les consommateursexécution simultanéeEntre les deux ensemble un tampon capable de stocker une pluralité de produits, les producteurs va produire le produit dans le tampon, les produits de consommation retirées de la mémoire tampon pour la consommation, de toute évidence doit être compris entre producteurs et consommateurs à suivre le rythme, non seulement ne permet pas aux consommateurs d'un produit d'enlèvement de tampon vides, mais aussi permettre au producteur d'ajouter des produits à un tampon complet.

En troisième lieu, le code de reproduction de scénario

 Tout d' abord, la nécessité de créer une classe de conteneur Queue, la capacité maximale du réservoir 4, le type est ArrayListle type de conteneur fournit deux méthodes, une méthode est stockée offer(), fournie aux appels de fil de producteur; Une autre méthode consiste à supprimer poll(), aux appels de fil à la consommation , pour répondre à maintenir la synchronisation entre les producteurs et les consommateurs, chaque méthode doit faire trois choses:

  • 1. Pour assurer la sécurité des threads, doit être conteneur verrouillé, qui ne peut faire le maintien de fil l'accès balise de verrouillage, à cette méthode nécessite une synchronizedmodification;
  • 2. Lorsque le récipient est vide ou plein temps (taille == 0 ou taille == 4), le fil correspondant en attente du consommateur ou de fils de consommateur indéfiniment, l' appel de la wait()méthode;
  • Ou moins de 3. Lorsque le conteneur est pas vide, les consommateurs de notification correspondant a ajouté les producteurs à produire, dépenserait entre producteurs et consommateurs de notification correspondant supprimé;

Insérer ici l'image Description

Simulation zone de tampon de données

//我的队列
class MyQueue {

    private List values = new ArrayList();

    private int max = 4;

    //存入队列
    public synchronized void offer(Object o){//E

        while(values.size() == max){
            //进来线程,停下
            try {
                this.wait();
                //被唤醒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notifyAll();
		values.add(o);
        System.out.println(Thread.currentThread().getName() + "存入元素 : "+ values );
    }

    //从队列取出
    public synchronized Object poll(){//1个元素

        while(values.size() == 0){
            try {
                this.wait();
                //被唤醒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.notifyAll();//唤醒因mq对象而进入无限期等待的线程对象(一个)

        return values.remove(0);
    }
}

simulation producteurs

 Le producteur est essentiellement un thread utilise ici deux producteurs, à savoir l' accès multi-thread, un objet de ressource critique Queue, seul le thread la marque de verrouillage lorsque l'objet peut accéder à l'objet, puis l'action appropriée.

//生产者1
class Produce1 extends Thread{
    MyQueue mq;
    public Produce1(MyQueue mq){
        this.mq = mq;
    }

    public void run(){
        System.out.println("Produce1启动");
        for (char ch = 'A'; ch <= 'E'; ch++) {
            mq.offer(ch);
        }
        System.out.println("Produce1结束");
    }
}
//生产者2
class Produce2 extends Thread{
    MyQueue mq;
    public Produce2(MyQueue mq){
        this.mq = mq;
    }

    public void run(){
        System.out.println("Produce2启动");
        for (char ch = 'F'; ch <= 'J'; ch++) {
            mq.offer(ch);
        }
        System.out.println("Produce2结束");
    }
}

simulation consommateurs

 Les consommateurs ont également un fil sur la nature, bien sûr, les consommateurs peuvent avoir les mêmes producteurs que plusieurs, même, seuls ceux qui ont les fils de consommation étiquetés blocage ont le droit d'exploiter l'objet des ressources critiques; Pour plus de commodité, pensez à un consommateur;

//消费者
class Consumer extends Thread{
    MyQueue mq;
    public Consumer(MyQueue mq){
        this.mq = mq;
    }

    public void run(){
        for (int i = 0 ; i < 10 ; i++) {//循环取数据
            System.out.println(mq.poll() + "被移除");
        }
    }
}

La fonction principale

 La fonction principale est de laisser toutes les discussions ouvertes peuvent être!

public static void main(String[] args) {

    MyQueue mq = new MyQueue();

    Produce1 p1 = new Produce1(mq);
    Produce2 p2 = new Produce2(mq);
    Consumer c1 = new Consumer(mq);

    p1.start();
    p2.start();
    c1.start();


    System.out.println("main end");
}

Les résultats d'exploitation

Insérer ici l'image Description
 imprimer clairement les résultats ont été très clairs tout au long du processus nous indique aux consommateurs et aux producteurs l'exécution simultanée, je crois que votre esprit a formé une image animée, j'espère que vous comprenez, il y a de l'aide! De si pratique, bien sûr, s'il vous plaît encouragez vos pouces! Soyez reconnaissants!

Publié 84 articles originaux · louange gagné 126 · vues 120 000 +

Je suppose que tu aimes

Origine blog.csdn.net/qq_44717317/article/details/104884787
conseillé
Classement