Java: ตัวอย่างผู้บริโภคของผู้ผลิต – จัดการการอ่าน/เขียนพร้อมกัน
เผยแพร่แล้ว: 2019-02-17 producer-consumer problem
(หรือที่เรียกว่า bounded-buffer problem
) เป็นตัวอย่าง Java คลาสสิกของปัญหาการซิงโครไนซ์หลายกระบวนการ
ปัญหาอธิบายสองกระบวนการ the producer
และ the consumer
ที่ใช้บัฟเฟอร์ขนาดคงที่ร่วมกันที่ใช้เป็นคิว หน้าที่ของโปรดิวเซอร์คือการสร้างข้อมูลบางส่วน ใส่ลงในบัฟเฟอร์แล้วเริ่มใหม่อีกครั้ง
ในเวลาเดียวกัน ผู้บริโภคกำลังใช้ข้อมูล (เช่น ลบออกจากบัฟเฟอร์) ทีละชิ้น ปัญหาคือต้องแน่ใจว่าผู้ผลิตจะไม่พยายามเพิ่มข้อมูลลงในบัฟเฟอร์หากเต็มและผู้บริโภคจะไม่พยายามลบข้อมูลออกจากบัฟเฟอร์ว่าง
ด้านล่างโปรแกรม Java อย่างง่ายจะสร้างปัญหานี้:
ตัวอย่าง 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
ในขณะที่เรากำลังใช้งาน
โปรแกรม 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 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 ) ; } } } } |