جافا: مثال المستهلك المنتج - التعامل مع القراءة / الكتابة المتزامنة
نشرت: 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 ) |

الدقة:
أضف الكلمة الأساسية synchronized
لوضع قفل على data
أثناء استخدامها.
برنامج جافا أفضل:
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 ) ; } } } } |