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----------------------------------------------------