1. Concept
Le problème des producteurs et des consommateurs est un problème de collaboration multithread en Jindian. Les producteurs sont responsables de la production de produits et de leur stockage dans l'entrepôt; Les consommateurs obtiennent des produits de l'entrepôt et les consomment. Lorsque l'entrepôt est plein, le producteur doit arrêter la production jusqu'à ce qu'il y ait un emplacement pour que le produit soit stocké; Lorsque l'entrepôt est vide, le consommateur doit arrêter la consommation jusqu'à ce qu'il y ait un produit dans l'entrepôt.
Les techniques suivantes sont principalement utilisées pour résoudre les problèmes des producteurs / consommateurs: 1. Utilisez des threads pour simuler les producteurs et stocker en continu les produits dans l'entrepôt dans la méthode de course. 2. Utilisez des threads pour simuler les consommateurs et obtenir en continu des produits de l'entrepôt dans la méthode de course. 3
Le . La classe d'entrepôt permet d'économiser le produit. Lorsque le nombre de produits est 0, la méthode d'attente est appelée, ce qui fait entrer le thread de consommation actuel dans un état d'attente. Lorsqu'un nouveau produit est stocké, la méthode de notification est appelée pour réveiller le fil de consommation en attente. Lorsque l'entrepôt est plein, la méthode d'attente est appelée, ce qui fait entrer le fil de producteur actuel dans un état d'attente. Lorsqu'un consommateur obtient le produit, la méthode de notification est appelée pour réveiller le fil du producteur en attente.
2. Exemples
Package Book.Thread.Product; public Class Consumer étend Thread {Private Warehouse Warehouse; // L'entrepôt où le consommateur obtient le produit Boolean Private Running = false; // est le bit de drapeau du thread final requis le consommateur public (entrepôt d'entrepôt, nom de chaîne) {super (nom); this.warehouse = entrepôt; } public void start () {this.running = true; super.start (); } public void run () {produit produit; essayez {while (running) {// obtenir un produit de l'entrepôt produit = warehouse.getProduct (); sommeil (500); }} catch (InterruptedException e) {e.printStackTrace (); }} // Stop the Consumer Thread public void stopConsumer () {synchronisé (warehouse) {this.running = false; warehouse.notifyall (); // informer le fil en attente de l'entrepôt}} // si le thread de consommation exécute publique booléen isrunning () {return running; }} Package Book.Thread.Product; Producteur de classe publique étend Thread {Private Warehouse Warehouse; // Le fabricant stocke l'entrepôt du produit Private Static int produceName = 0; // Nom du produit du produit Boolean Running = False; // Le bit de drapeau du thread final est requis public (Warehouse Warehouse, nom de chaîne) {super (nom); this.warehouse = entrepôt; } public void start () {this.running = true; super.start (); } public void run () {produit produit; // Produire et stocker le produit try {while (running) {Product = new Product ((++ ProductName) + ""); this.warehouse.storageProduct (produit); sommeil (300); }} catch (InterruptedException e) {e.printStackTrace (); }} // Stop the Producer Thread public void stopProduner () {synchronisé (warehouse) {this.running = false; // informer le fil en attente de l'entrepôt d'entrepôt d'entrepôt d'entrepôt.notifyall (); }} // si le thread producteur exécute publique booléen isrunning () {return running; }} package book.thread.product; public class Product {private String Name; // Nom du produit Product public (nom de chaîne) {this.name = name; } public String toString () {return "Product -" + name; }} package book.thread.product; // La classe d'entrepôt du produit utilise un tableau pour représenter une file d'attente circulaire pour stocker le produit Public Class Warehouse {Products static privé dans l'entrepôt // Produits dans l'intervalle [avant, à l'arrière, n'est pas consommé INTRACT privé Front = 0; // // sous la sous-inscripie du premier produit dans le produit privé Front = 0; // sous la sous-année de la premièreoconte du Consérée du Curvey. int arrière = 0; // Indice du dernier produit non consommé dans l'entrepôt plus 1 entrepôt public () {this.products = nouveau produit [capacité]; } Public Warehouse (int la capacité) {this (); if (capacité> 0) {Capacité = capacité +1; this.products = nouveau produit [capacité]; }} // Obtenez un produit du produit public GetProduct () lance InterruptedException {synchronisé (this) {boolean Consumerrunning = true; // Tag si le thread de consommation est toujours en cours d'exécution CurrentThread = thread.currentThread (); // Obtenez le thread actuel If (actuel Instruction de consommation) {ConsumerRunning = ((consommateur) CurrentThread). } else {return null; // pas le consommateur peut obtenir le produit} // Si le thread de consommation est en cours d'exécution, mais il n'y a pas de produit dans l'entrepôt, le fil de consommation continue d'attendre while ((front == arrière) && consommateur) {wait (); Consumerrunning = ((consommateur) CurrentThread) .isrunning (); } // Si le thread de consommation a cessé d'exécuter, quittez la méthode et annulez le produit if (! Consumerrunning) {return null; } // Obtenez le premier produit qui n'a pas été consommé actuel produit produit = produits [avant]; System.out.println ("Consumer [" + CurrentThread.getName () + "] GetProduct:" + Product); // Déplacez l'indice du produit actuellement non consommé un par un, s'il atteint la fin du tableau, passez à la capacité avant = (avant + 1 + capacité)%; System.out.println ("La quantité de produits non encore consommés dans l'entrepôt:" + (arrière + capacité à front)%); // informer les autres threads d'attente Notify (); produit de retour; }} // Stockage Un produit dans l'entrepôt public void StorageProduct (produit produit) lève InterruptedException {synchronisé (this) {boolean productorrunning = true; // signe si le thread producteur exécute le thread currentThread = thread.currentThread (); if (CurrentThread instance of produner) {productrunning = ((producteur) currentThread) .isrunning (); } else {return; } // Si le dernier produit non consommé est à côté de l'indice du premier produit non consommé, cela signifie qu'il n'y a pas d'espace de stockage. // s'il n'y a pas d'espace de stockage et que le fil de producteur est toujours en cours d'exécution, le fil de producteur attend que l'entrepôt relâche le produit tandis que ((arrière + 1)% capacile == avant) && productorrunning) {wait (); productorrunning = ((producteur) currentthread) .isrunning (); } // Si le thread de production a cessé de fonctionner, le stockage du produit est arrêté si (! Productorrunning) {return; } // Enregistrer le produit sur les produits d'entrepôt [arrière] = produit; System.out.println ("producteur [" + thread.currentThread (). GetName () + "] StorageProduct:" + Product); // modifie l'indice arrière par l'un après l'autre. Arrière = (arrière + 1)% capacité; System.out.println ("La quantité de produits non consommés dans l'entrepôt:" + (arrière + capacité -front)% Capacité); notify (); }}} package book.thread.product; public class TestProduct {public static void main (String [] args) {warehouse warehouse = nouvel entrepôt (10); // créer un entrepôt avec une capacité de 10 // créer des threads producteurs et des producteurs de consommateurs de consommateurs1 = nouveau producteur (Warehouse, "producteur-"); Producteur produrs2 = nouveau producteur (entrepôt, "producteur-2"); Producteur producteur3 = nouveau producteur (Warehouse, "Producer-3"); Consumer Consumer1 = nouveau consommateur (entrepôt, "Consumer-1"); Consumer Consumer2 = nouveau consommateur (entrepôt, "Consumer-2"); Consumer Consumer3 = nouveau consommateur (entrepôt, "Consumer-3"); Consumer Consumer4 = nouveau consommateur (entrepôt, "Consumer-4"); // Démarrez le thread producteur et le thread de consommation produit1.start (); producteurs2.start (); Consumer1.start (); producteurs3.start (); Consumer2.Start (); Consumer3.Start (); Consumer4.Start (); // Laissez le programme producteur / consommateur fonctionner pendant 1600 ms essayer {Thread.Sleep (1600); } catch (InterruptedException e) {e.printStackTrace (); } // Arrêtez le thread de consommation produit1.stopproducer (); Consumer1.StopConsumer (); produrs2.stopproducer (); Consumer2.StopConsumer (); produrs3.StopProducer (); Consumer3.StopConsumer (); Consumer4.StopConsumer (); }}Résultat de sortie:
Producteur [producteur-1] Storage Produit: le nombre de produits qui n'ont pas été consommés dans l'entrepôt Product-1: 1Consumer [Consumer-2] GetProduct: Le nombre de produits qui n'ont pas été consommés dans l'entrepôt Product-1: 0 Producteur [Producteur-3] Storage Product: le nombre de produits qui n'ont pas été consommés dans le produit-3 Warehouse: 1 Produceur [Producteur-2] n'ont pas été consommés dans l'entrepôt du produit-2: 2Consumer [Consumer-3] GetProduct: Le nombre de produits qui n'ont pas été consommés dans l'entrepôt du produit-3: 1Consumer [Consumer-1] GetProduct: le nombre de produits qui n'ont pas été consommés dans le nombre de produits qui n'ont pas été consommés: Produce - Product-1] 1Consumer [Consumer-4] GetProduct: Le nombre de produits qui n'ont pas été consommés dans l'entrepôt Product-4: 0Producer [producteur-3] Storage Product: Le nombre de produits qui n'ont pas été consommés dans le produit-6: 1 Producer [Producteur-2] Storage Product: Le nombre de produits qui n'ont pas été consommés dans le produit-5 Warehouse: 2Consumer [Conser-1] GETPRODUCT: Le nombre de produits qui n'ont pas été consommés dans l'entrepôt du produit-6: 1Consumer [Consumer-2] GetProduct: Le nombre de produits qui n'ont pas été consommés dans l'entrepôt du produit-5: 0 Producer [Product-1] Storage Product: le nombre de produits qui n'ont pas été consommés dans le produit - 7 ans: 1Consumer [consommateur-3 Dans le produit-7 entrepôt: 0Producer [product-3] Storage Produit: le nombre de produits qui n'ont pas été consommés dans l'entrepôt Product-8: 1Producer [Producer-2] Storage Produit: Product-9 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 2Consumer [Consumer-4] Getproduct: Product-8 Nombre de produits 1 Producer [product-1] Storage Produit: Produit-10 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 2Producer [product-3] Storage Product: Product-11 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 3Producer [Product-2] Storage Product: Product-12 Nombre de produits: Product-9 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 3Consumer [Consumer-2] GetProduct: Product-10 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 2Consumer [Consumer-3] GetProduct: Product-11 Nombre de produits: Product-13 Numéro de produits qui n'ont pas été consommés: Consommée: Product: Product-13 Numéro de produits qui n'ont pas été consommés dans le WareSho 2Producteur [ProductR-1] Storage Produit: Produit-14 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 3Producer [Producer-2] Storage Produit: Product-15 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 4Consumer [consommateur-4] GETPRODUCT: Product-12 Nombre de produits qui n'ont pas été consommés dans le Warehouse: 3Conmer Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 2Consumer [Consumer-2] GetProduct: Product-14 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 1 Producer [Product-1] Storage Product: Product-16 Nombre de produits qui n'ont pas été consommés dans l'entrepôt: 2 Producecer [Producteur-3] Strangement: Nombre de produits 3Producer [product-2] Storage Produit: Nombre de produits qui n'ont pas été consommés dans l'entrepôt produit-18: 4
Analyse: Un entrepôt de produit est établi dans la méthode principale, et l'entrepôt n'associe pas 3 fils de producteur et 4 fils de consommation. Ces fils sont lancés pour faire fonctionner le modèle producteur / consommateur. Lorsque le programme fonctionne pendant 1600 ms, tous les producteurs cessent de produire des produits et les consommateurs cessent de consommer des produits.
Le produit de thread producteur produit un produit sans 300 ms dans la méthode d'exécution et le stocke dans l'entrepôt; Le consommateur de thread consommateur prend un produit de l'entrepôt sans 500 ms dans la méthode d'exécution.
L'entrepôt est responsable du stockage et de la distribution des produits. La méthode de stockage de stockage est responsable du stockage du produit. Lorsque l'entrepôt est plein, le thread actuel entre dans un état d'attente, c'est-à-dire que si le thread producteur A appelle la méthode de stockage de stockage pour stocker le produit, il constate que l'entrepôt est plein et ne peut pas être stocké, il entrera dans un état d'attente. Lorsque le produit de stockage réussit, la méthode de notification est appelée pour réveiller le fil de consommation en attente.
La méthode GetProduct est responsable du produit à l'avance. Lorsque l'entrepôt est vide, le fil actuel entre dans un état d'attente. Autrement dit, si le thread Consumer B appelle la méthode GetProduct pour obtenir le produit, il constate que l'entrepôt est vide, il entrera dans un état d'attente. Lorsque le produit est extrait avec succès, la méthode de notification est appelée pour réveiller le fil du producteur en attente.
L'article ci-dessus discute brièvement des problèmes des producteurs et des consommateurs dans les threads Java est tout le contenu que je partage avec vous. J'espère que cela pourra vous donner une référence et j'espère que vous pourrez soutenir Wulin.com plus.