前阵子学习了多线程,现在进行总结一下,模拟队列。
分析问题:
(1)首先需要一个容器存放元素,这里用linkedList队列。
(2)每次像容器中添加或删除元素的时候需要计数,所以这里需要一个计数器,这里用原子类的atomicInter实现。
(3)需要三个方法,一个put()方法,向容器中推数据,一个take()方法,向容器中取数据,一个size()方法,返回当前容器的大小。
实现代码如下:
public class MyQueue { //队列 private volatile LinkedList<Object> linkedList=new LinkedList<Object>(); //队列最大数 private int maxSize; //队列最小数 private int minSize=0; //计数器 private AtomicInteger count=new AtomicInteger(0); //创建锁 private Object lock=new Object(); //初始化队列大小 public MyQueue(int maxSize){ this.maxSize=maxSize; } //返回当前队列的大小 public int getSize(){ return count.get(); } //向队列添加元素方法 public void put(Object obj){ synchronized(lock){ if(getSize()==maxSize){ System.out.println("线程进入put方法中,阻塞中..."); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } linkedList.add(obj); count.getAndIncrement(); System.out.println("向队列中添加元素:"+obj); lock.notify();//当容器大小为minSize时,且线程进行take操作时,执行了wait方法,进入了阻塞状态,所以添加完数据应该唤醒线程,进行数据take操作 } } //向队列中取出元素 public Object take(){ Object temp=""; synchronized(lock){ if(getSize()==minSize){ System.out.println("线程进入take方法中,阻塞中..."); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } temp=linkedList.removeFirst(); count.getAndDecrement(); System.out.println("被取出的元素为:"+temp); lock.notify();//当容器大小为maxSize时,且线程进行put操作时,执行了wait方法,进入了阻塞状态,所以取完数据应该唤醒线程,进行数据put操作 } return temp; } public static void main(String []args){ //初始化容器 final MyQueue myQueue=new MyQueue(5); myQueue.put("A"); myQueue.put("B"); myQueue.put("C"); myQueue.put("D"); myQueue.put("E"); Thread t1=new Thread(new Runnable() { public void run() { myQueue.put("F"); } },"t1"); Thread t2=new Thread(new Runnable() { public void run() { myQueue.take(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } },"t2"); Thread t3=new Thread(new Runnable() { public void run() { myQueue.take(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } },"t3"); Thread t4=new Thread(new Runnable() { public void run() { myQueue.put("G"); } },"t4"); t1.start(); t2.start(); t3.start(); t4.start(); } }