Java: 생산자 소비자 예제 – 동시 읽기/쓰기 처리
게시 됨: 2019-02-17 producer-consumer problem
( bounded-buffer problem
이라고도 함)는 다중 프로세스 동기화 문제의 고전적인 Java 예제입니다.
문제는 대기열로 사용되는 공통 고정 크기 버퍼를 공유하는 the producer
와 the consumer
의 두 프로세스를 설명합니다. 생산자의 작업은 데이터 조각을 생성하고 버퍼에 넣고 다시 시작하는 것입니다.
동시에 소비자는 데이터를 한 번에 한 조각씩 소비합니다(즉, 버퍼에서 제거). 문제는 버퍼가 가득 찬 경우 생산자가 버퍼에 데이터를 추가하지 않고 소비자가 빈 버퍼에서 데이터를 제거하지 않도록 하는 것입니다.
간단한 Java 프로그램 아래에서 이 문제가 발생합니다.
자바 예제 – 생산자 소비자 문제
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 ) ; } } } } |
문제:
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 ) |

해결:
데이터를 사용하는 동안 data
를 잠그기 위해 synchronized
된 키워드를 추가합니다.
더 나은 자바 프로그램:
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 ) ; } } } } |