Java: Producer-Consumer-Beispiel – Behandeln Sie gleichzeitiges Lesen/Schreiben
Veröffentlicht: 2019-02-17 Das producer-consumer problem
(auch bekannt als bounded-buffer problem
) ist ein klassisches Java-Beispiel für ein Synchronisationsproblem mit mehreren Prozessen.
Das Problem beschreibt zwei Prozesse, the producer
und the consumer
, die sich einen gemeinsamen Puffer fester Größe teilen, der als Warteschlange verwendet wird. Die Aufgabe des Producers besteht darin, ein Datenelement zu generieren, es in den Puffer zu legen und von vorne zu beginnen.
Gleichzeitig verbraucht der Konsument die Daten Stück für Stück (dh er entfernt sie aus dem Puffer). Das Problem besteht darin, sicherzustellen, dass der Erzeuger nicht versucht, Daten in den Puffer hinzuzufügen, wenn er voll ist, und dass der Verbraucher nicht versucht, Daten aus einem leeren Puffer zu entfernen.
Das folgende einfache Java-Programm wird dieses Problem verursachen:
Java-Beispiele – Producer-Consumer-Problem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
package com . crunchify . tutorials ; import java . util . Vector ; import java . util . Iterator ; /** * @author Crunchify */ public class CrunchifyProducerConsumer { private static Vector <Object> data = new Vector <Object> ( ) ; public static void main ( String [ ] args ) { new Producer ( ) . start ( ) ; new Consumer ( ) . start ( ) ; } public static class Consumer extends Thread { Consumer ( ) { super ( "Consumer" ) ; } @Override public void run ( ) { for ( ; ; ) { try { Thread . sleep ( 1 ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } @SuppressWarnings ( "rawtypes" ) Iterator it = data . iterator ( ) ; while ( it . hasNext ( ) ) it . next ( ) ; } } } public static class Producer extends Thread { Producer ( ) { super ( "Producer" ) ; } @Override public void run ( ) { for ( ; ; ) { try { Thread . sleep ( 1 ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } data . add ( new Object ( ) ) ; if ( data . size ( ) > 1000 ) data . remove ( data . size ( ) - 1 ) ; } } } } |
Problem:
1 2 3 4 |
Exception in thread "Consumer" java . util . ConcurrentModificationException at java . util . ArrayList $ Itr . checkForComodification ( ArrayList . java : 819 ) at java . util . ArrayList $ Itr . next ( ArrayList . java : 791 ) at com . crunchify . tutorials . CrunchifyProducerConsumer $ Consumer . run ( CrunchifyProducerConsumer . java : 36 ) |

Auflösung:
Fügen Sie das Schlüsselwort synchronized
hinzu, um die data
zu sperren, während wir sie verwenden.
Besseres Java-Programm:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
package crunchify . com . tutorials ; import java . util . Iterator ; import java . util . Vector ; /** * @author Crunchify.com * Producer Consumer Example in Java */ public class CrunchifyProducerConsumer { private static Vector <Object> data = new Vector <Object> ( ) ; public static void main ( String [ ] args ) { new Producer ( ) . start ( ) ; new Consumer ( ) . start ( ) ; } public static class Consumer extends Thread { Consumer ( ) { super ( "Consumer" ) ; } @SuppressWarnings ( "rawtypes" ) @Override public void run ( ) { for ( ; ; ) { try { Thread . sleep ( 1000 ) ; System . out . println ( "Object Consumed ################" ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } synchronized ( data ) { Iterator it = data . iterator ( ) ; while ( it . hasNext ( ) ) it . next ( ) ; } } } } public static class Producer extends Thread { Producer ( ) { super ( "Producer" ) ; } @Override public void run ( ) { for ( ; ; ) { try { Thread . sleep ( 1000 ) ; System . out . println ( "Object Produced ~~~~~~~~~~~~~~~" ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } data . add ( new Object ( ) ) ; if ( data . size ( ) > 1000 ) data . remove ( data . size ( ) - 1 ) ; } } } } |