Simulated blocking Queue in concurrent programming

Keywords: Java

I. use wait/notify to simulate Queue

BlockingQueue: first of all, it is a queue, and supports blocking mechanism. Blocking puts and gets data. We need to implement the following two simple methods of LinkedBlockingQueue: put and take.
put(Object): add object to BlockingQueue. If BlockingQueue has no space, the thread calling this method will be blocked until there is space in BlockingQueue.
Take: take away the first object in BlockingQueue. If BlockingQueue is empty, block entering the waiting state until new data is added to BlockingQueue.

Two, example

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * Simulated blocking Queue
 * @author shixiangcheng
 * 2019-06-30
 */
public class MyQueue {
    //Define a collection of storage elements
	private LinkedList<Object> list=new LinkedList<Object>();
	//Counter
	private AtomicInteger count=new AtomicInteger(0);
	private final int minSize=0;
	private final int maxSize;
	public MyQueue(int size){
		this.maxSize=size;
	}
	//Initializes an object for locking
	private final Object lock=new Object();
	//Add object to BlockingQueue. If BlockingQueue has no space, the thread calling this method will be blocked until there is space in BlockingQueue.
	public void put(Object obj){
		synchronized(lock){
			while(count.get()==this.maxSize){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			list.add(obj);
			//Counter accumulation
			count.incrementAndGet();
			//Notify another thread
			lock.notify();
			System.out.println("The newly added element is:"+obj);
		}
	}
	//Remove the first object in BlockingQueue. If BlockingQueue is empty, block entering the waiting state until new data is added to BlockingQueue.
	public Object take(){
		Object ret=null;
		synchronized(lock){
			while(count.get()==this.minSize){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			//Removing Elements
			ret=list.removeFirst();
			//Counter decrement
			count.decrementAndGet();
			lock.notify();
			System.out.println("Removed elements are:"+ret);
		}
		return ret;
	}
	public int getSize(){
		return this.count.get();
	}
	public static void main(String[] args) throws Exception{
		final MyQueue mq=new MyQueue(5);
		mq.put("a");
		mq.put("b");
		mq.put("c");
		mq.put("d");
		mq.put("e");
		System.out.println("Current container length:"+mq.getSize());
		Thread t1=new Thread(new Runnable(){
			@Override
			public void run() {
				mq.put("f");
				mq.put("g");
			}
		},"t1");
		t1.start();
		Thread t2=new Thread(new Runnable(){
			@Override
			public void run() {
				mq.take();
				mq.take();
			}
		},"t2");
		TimeUnit.SECONDS.sleep(2);
		t2.start();
	}
}

Operation result

The newly added element is: a
 The newly added element is: b
 The newly added element is: c
 The newly added element is: d
 The newly added element is: e
 Current container length: 5
 The removed elements are: a
 The newly added element is: f
 The removed element is: b
 The newly added element is: g

-------------------------------END----------------------------------------------------

Posted by Graeme1972 on Sat, 02 Nov 2019 19:51:09 -0700