1. Concepto
El problema de los productores y consumidores es un problema de colaboración multiproceso en Jindian. Los productores son responsables de producir productos y almacenarlos en el almacén; Los consumidores obtienen productos del almacén y los consumen. Cuando el almacén está lleno, el productor debe detener la producción hasta que haya una ubicación para que el producto se almacene; Cuando el almacén está vacío, el consumidor debe detener el consumo hasta que haya un producto en el almacén.
Las siguientes técnicas se utilizan principalmente para resolver problemas de productores/consumidores: 1. Use hilos para simular a los productores y almacenar continuamente productos en el almacén en el método de ejecución. 2. Use hilos para simular a los consumidores y obtener continuamente productos del almacén en el método de ejecución. 3
El . La clase de almacén salva el producto. Cuando el número de productos es 0, se llama el método de espera, lo que hace que el hilo del consumidor actual ingrese a un estado de espera. Cuando se almacena un nuevo producto, se llama al método Notify para despertar el hilo del consumidor que espera. Cuando el almacén está lleno, se llama el método de espera, lo que hace que el hilo del productor actual ingrese a un estado de espera. Cuando un consumidor obtiene el producto, se llama al método Notify para despertar el hilo del productor de espera.
2. Ejemplos
paquete book.thread.product; Public Class Consumer extiende el hilo {Almacenamiento de almacén privado; // El almacén donde el consumidor obtiene el producto privado boolean running = false; // es el bit de la bandera del hilo final requerido al consumidor público (almacén de almacén, nombre de cadena) {súper (nombre); this.warehouse = almacén; } public void start () {this.running = true; super.Start (); } public void run () {producto producto; Pruebe {While (Running) {// Obtener producto del almacén de productos = warehouse.getProduct (); dormir (500); }} catch (InterruptedException e) {E.PrintStackTrace (); }} // Detener el hilo del consumidor public void stopConsumer () {Synchronized (Warehouse) {this.running = false; warehouse.notifyAll (); // notificar hilo esperando el almacén}} // si el hilo del consumidor está ejecutando público boolean isrunning () {return running; }} paquete book.thread.product; Public Class Producer extiende Thread {Private Warehouse Warehouse; // El fabricante almacena el almacén del producto Private static int productename = 0; // El nombre del producto Boolean Running = False; // El bit de la bandera del hilo final es el productor público requerido (Warehouse Warehouse, Nombre de cadena) {Nombre); this.warehouse = almacén; } public void start () {this.running = true; super.Start (); } public void run () {producto producto; // producir y almacenar el producto try {while (en ejecución) {producto = nuevo producto ((++ ProductName)+""); this.wareHouse.StorageProduct (producto); dormir (300); }} catch (InterruptedException e) {E.PrintStackTrace (); }} // Detener el hilo del productor public void stopProducer () {sincronizado (warehouse) {this.running = false; // notifica al hilo esperando el almacén de almacén almacenado almacén. }} // Si el hilo del productor está ejecutando públicamente boolean isrunning () {return running; }} paquete book.thread.product; public class Product {private String Name; // Nombre del producto Producto público (nombre de cadena) {this.name = name; } public String toString () {return "Product-"+nombre; }} paquete book.thread.product; // La clase de almacén del producto utiliza una matriz para representar una cola circular para almacenar el producto de la clase pública almacenamiento de la clase {private static int capacidad = 11; // La capacidad del producto privado de almacén [] productos; // productos en el almacén // productos en el intervalo de frontal en el intervalo de frontal no se consume privado intencion = 0;//subscript de la subscrit de el subscrit de la subscrit de la subscript de la primera subscrit de los productos de la altura de la primera. Private int REAR = 0; // Subíndico del último producto no consumen en el almacén más 1 Public Warehouse () {this.products = New Product [Capacidad]; } Public Warehouse (int capacidad) {this (); if (capacidad> 0) {capacidad = capacidad +1; this.products = nuevo producto [capacidad]; }} // Obtenga un producto del producto público de almacén getProduct () lanza interruptedException {SynChronized (this) {boolean consuming = true; // etiqueta si el hilo de consumidor todavía está ejecutando hilo actual = thread.currentThread (); // obtiene el hilo actual si (instancia de readear de readear) {consumer = ((consumidor). } else {return null; // no el consumidor puede obtener el producto} // Si el hilo del consumidor se está ejecutando, pero no hay producto en el almacén, el hilo del consumidor continúa esperando mientras ((front == retroceso) && consuming) {Wait (); consumering = (((consumidor) CurrentThread) .isrunning (); } // Si el hilo del consumidor ha dejado de funcionar, salga del método y cancele el producto if (! ConsumerRunning) {return null; } // Obtenga el primer producto que no se ha consumido en el actual Producto Producto = Productos [Frente]; System.out.println ("Consumer ["+currentThread.getName ()+"] GetProduct:"+Product); // Mueve el subíndice del producto no consumen actualmente uno por uno, si alcanza el final de la matriz, muévase al frente del encabezado = (frente+1+capacidad)%de capacidad; System.out.println ("La cantidad de productos aún no se consume en el almacén:"+(trasero+capacidad frente)%de capacidad); // notificar a otros hilos de espera notify (); producto de devolución; }} // almacenamiento de un producto para el almacén de almacenamiento de almacenamiento público void (producto del producto) arroja interruptedException {SynChronized (this) {boolean productRunning = true; // firmar si el hilo del productor está ejecutando el hilo actual = thread.currentThread (); if (instancia actual del productor) {productRunning = ((productor) currentthread) .isrunning (); } else {return; } // Si el último producto no consumen al lado del subíndice del primer producto no consumido, significa que no hay espacio de almacenamiento. // Si no hay espacio de almacenamiento y el hilo del productor todavía se está ejecutando, el hilo del productor espera a que el almacén libere el producto mientras (((((((1) 1)%Capacidad == front) && ProducerRunning) {Wait (); producerRunning = ((productor) CurrentThread) .isrunning (); } // Si el hilo de producción ha dejado de funcionar, el almacenamiento del producto se detiene si (! ProducerRunning) {return; } // Guardar el producto en los productos de almacén [trasero] = producto; System.out.println ("Producer [" + Thread.CurrentThread (). GetName () + "] StorageProduct:" + Product); // Cambiar el subíndice trasero por uno tras otro. Trasero = (trasero + 1)%de capacidad; System.out.println ("La cantidad de productos no consumidos en el almacén:" + (Capacidad posterior -front)%de capacidad); notificar(); }}} paquete book.thread.product; public class testProduct {public static void main (string [] args) {warehouse warehouse = new Warehouse (10); // Crear un almacén con una capacidad de 10 // crea hilos de productores y productores de consumidores productores1 = nuevo productor (warehouse "" productor-1 "); Productores productores2 = nuevo productor (almacén, "productor-2"); Productores productores3 = nuevo productor (almacén, "productor-3"); Consumer Consumer1 = nuevo consumidor (almacén, "Consumer-1"); Consumer Consumer2 = nuevo consumidor (almacén, "Consumer-2"); Consumer Consumer3 = nuevo consumidor (almacén, "Consumer-3"); Consumer Consumer4 = nuevo consumidor (almacén, "Consumer-4"); // iniciar el hilo del productor y el hilo de consumo produce 1.Start (); productores2.start (); Consumer1.Start (); productores3.start (); Consumer2.start (); Consumer3.start (); Consumer4.Start (); // deja que el programa de productor/consumidor se ejecute para 1600 ms intente {Thread.sleep (1600); } catch (InterruptedException e) {E.PrintStackTrace (); } // detener el hilo del consumidor produce1.stopProducer (); Consumer1.stopconsumer (); productores2.stopProducer (); Consumer2.stopconsumer (); productores3.stopProducer (); Consumer3.stopconsumer (); Consumer4.stopconsumer (); }}Resultado de salida:
Productor [productor-1] almacenamiento de almacenamiento: el número de productos que no se han consumido en el almacén del producto-1: 1Consumer [Consumer-2] GetProduct: el número de productos que no se han consumido en el almacén del producto-1: 0 Producer [Productor-3] productor: el número de productos que no se han consumido en el producto-3 Warehouse: 1 productor [productor] have not been consumed in the Product-2 warehouse: 2Consumer[consumer-3] getProduct: The number of products that have not been consumed in the Product-3 warehouse: 1Consumer[consumer-1] getProduct: The number of products that have not been consumed in the Product-2 warehouse: 0Producer[producter-1] storageProduct: The number of products that have not been consumed in the Product-4 warehouse: 1Consumer [Consumer-4] GetProduct: el número de productos que no se han consumido en el almacén del producto-4: 0 PRODUCTER [Productor-3] StorageProduct: el número de productos que no se han consumido en el almacén de productos 6: 1 PRODUCTER [Productor-2] StorageProduct: el número de productos que no se han consumido en el producto-5 Warehouse: 2consumer [Consumer-1 de almacenamiento] GetProduct: el número de productos que no se han consumido en el almacén del producto-6: 1Consumer [Consumer-2] GetProduct: el número de productos que no se han consumido en el almacén del producto-5: 0 Producer [ProductR-1] StorageProduct: el número de productos que no se han consumido en el producto-7 Warehouse: 1Consumer [Consumer-3] GetProduct: el número de productos no ha sido consumido en el producto-1 Warehouse: 1Consumer [Consumer-3] GetProduct: el número de productos no ha sido consumido en el producto-7 Warehous En el almacén del producto-7: 0 Producer [ProductR-3] StorageProduct: el número de productos que no se han consumido en el almacén del producto-8: 1 Productor [Producer-2] StorageProduct: Product-9 Número de productos que no se han consumido en el almacén: 2Consumer [Consumer-4] GetProduct: Product-8 Número de productos que no se han consumido en el Warehouse: 1Producer [ProductR-1] StorageProduct: Product-10 Número de productos que no se han consumido en el almacén: 2 Producer [ProductR-3] StorageProduct: Product-11 Número de productos que no se han consumido en el almacén: 3ProDucer [ProductR-2] StorageProduct: Product-12 Número de productos que no se han consumido en el Warehouse: 4Consumer [Consumer-1] Number of products that have not been consumed in the warehouse: 3Consumer[consumer-2] getProduct:Product-10 Number of products that have not been consumed in the warehouse: 2Consumer[consumer-3] getProduct:Product-11 Number of products that have not been consumed in the warehouse: 1Producer[productr-3] storageProduct:Product-13 Number of products that have not been consumed in the warehouse: 2Producer [ProductR-1] StorageProduct: Product-14 Número de productos que no se han consumido en el almacén: 3producer [Producer-2] StorageProduct: Product-15 Número de productos que no se han consumido en el almacén: 4Consumer [Consumer-4] GetProduct: Product-12 Número de productos que no se han consumido en el Warehouse: 3Consumer [Consumer-4] Número de productos que no se han consumido en el almacén: 2Consumer [Consumer-2] GetProduct: Producto-14 Número de productos que no se han consumido en el almacén: 1 Producer [ProductR-1] StorageProduct: Product-16 Número de productos que no se han consumido en el almacén: 2 Productor [Producer-3] StorageProduct: Número de productos que no se han consumido en el producto-17: 3Producer [Productr-2] StorageProduct: Número de productos que no se han consumido en el almacén del producto-18: 4
Análisis: un almacén de productos se establece en el método principal, y el almacén no asocia 3 hilos productores y 4 hilos de consumo. Estos hilos comienzan a hacer que el modelo de productor/consumidor funcione. Cuando el programa funciona durante 1600 ms, todos los productores dejan de producir productos y los consumidores dejan de consumir productos.
El producto de hilo de productor produce un producto sin 300 ms en el método de ejecución y lo almacena en el almacén; El consumidor del consumidor toma un producto del almacén sin 500 ms en el método de ejecución.
Warehouse es responsable de almacenar y distribuir productos. El método StorageProduct es responsable de almacenar el producto. Cuando el almacén está lleno, el hilo actual entra en un estado de espera, es decir, si el productor de un hilo A llama al método de almacenamiento para almacenar el producto, encuentra que el almacén está lleno y no se puede almacenar, ingresará a un estado de espera. Cuando el producto de almacenamiento es exitoso, se llama al método de notificación para despertar el hilo del consumidor que espera.
El método GetProduct es responsable del producto por adelantado. Cuando el almacén está vacío, el hilo actual entra en un estado de espera. Es decir, si el hilo del consumidor B llama al método GetProduct para obtener el producto, encuentra que el almacén está vacío, entrará en un estado de espera. Cuando el producto se extrae con éxito, se llama al método de notificación para despertar el hilo del productor que espera.
El artículo anterior discute brevemente los problemas de los productores y consumidores en Java Threads es todo el contenido que comparto con usted. Espero que pueda darle una referencia y espero que pueda apoyar más a Wulin.com.