BlockingQueue, ProducerConsumer

Kategori: Java , 21 Temmuz 2019 , JanFranco


Producer consumer problemi paralel programlamadaki giriş problemlerdendir. Aynı anda çalışan yani eş zamanlı çalışan 2 task, işlem vardır. Bunlardan biri üretici, diğeri tüketicidir. Amaç ortadaki ürünün bitmemesidir. Yani producer task bir şey üretecek, consumer task o şeyi tüketecek. Bu iki işlem aynı anda olacak. Amaç ortadaki şeyin bitmemesidir.

BlockingQueue yapısı Threadler için oluşturulmuş bir queue yapısıdır. Queue yapısını daha önce görmüştük. BlockingQueue eğer boş ise dequeue, dolu ise enqueue yapmamızı limitleyen bir kontrol mekanizması da vardır. BlockingQueue yapısını kullanarak ProducerConsumer problemini çözelim:


import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ProducerConsumer {

	Random random = new Random();
	BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
	
	public void produce() {
		
		while(true) {
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			int value = random.nextInt(100);
			try {
				queue.put(value);
				System.out.println("Producer is producing...");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
					
		}
		
	}
	
	public void consume() {
		
		while(true) {
			
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			try {
				queue.take();
				System.out.println("Consumer is consuming...");
				System.out.println("Queue size: " + queue.size());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}
		
	}
	
}
Burada producer saniyede bir ürün üretecek, consumer 5 saniyede bir tüketecektir. Threadleri oluşturup görelim:


public class Main_class {
	
	public static void main(String[] args){
		
		ProducerConsumer pc = new ProducerConsumer();
		
		Thread producer = new Thread(new Runnable() {
			
			@Override
			public void run() {
				pc.produce();
			}
		});
	
		Thread consumer = new Thread(new Runnable() {
			
			@Override
			public void run() {
				pc.consume();
			}
		});
		
		producer.start();
		consumer.start();
		
		try {
			producer.join();
			consumer.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}
Sonuç:

Producer is producing...
Producer is producing...
Producer is producing...
Producer is producing...
Consumer is consuming...
Queue size: 3
Producer is producing...
Producer is producing...
Producer is producing...
Producer is producing...
Producer is producing...
Consumer is consuming...
Queue size: 7
Producer is producing...
Producer is producing...
Producer is producing...
Consumer is consuming...
Queue size: 10
Producer is producing...
Consumer is consuming...
Producer is producing...
Queue size: 10
Consumer is consuming...
Producer is producing...
Queue size: 10
Consumer is consuming...
Producer is producing...
Queue size: 10
Consumer is consuming...
Producer is producing...
Queue size: 10


Sonraki Yazı: wait, notify
Yorumlar

Henüz bir yorum bulunmuyor.
Yorum bırakın