隊列是一種先進先出或者後進後出的數據結構。在此我們模擬一下隊列這種數據結構:
MyQueue.java定義如下:
public class MyQueue {
//隊列的容器
private LinkedList<Object> list = new LinkedList<Object>();
//計數器 int count
private final AtomicInteger count = new AtomicInteger(0);
//最大容量
private int maxSize;
//最小容量
private int minSize = 0;
//鎖
private final Object lock = new Object();
public MyQueue() {
this(16);
}
public MyQueue(int maxSize) {
this.maxSize = maxSize;
}
public void put(Object obj) {
synchronized (lock) {
while(count.get() == maxSize) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(obj); //將新的元素添加到容器裏
System.out.println("新增前容器長度:" + count.get());
count.getAndIncrement();
System.out.println("新增後容器長度:" + count.get());
lock.notify(); //喚醒線程
}
}
public Object take() {
Object temp = null;
synchronized (lock) {
while(count.get() == minSize) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
temp = list.removeFirst(); //從容器中移除第一個元素
System.out.println("自減之前的長度:" + count.get());
count.getAndDecrement();
System.out.println("自減之後的長度:" + count.get());
lock.notify();
}
return temp;
}
public int size() {
return count.get();
}
public List<Object> getQueueList() {
return list;
}
}
該隊列的數據結構爲一個List< Object> 作爲容器來盛裝數據,此外還有幾個變量,分別是count計數器和maxSize,minSize最大最小容量的標誌,此外還有lock鎖。此類有3個核心方法,分別是size()返回隊列長度的方法,take()移除節點方法和put()添加節點方法。
該隊列的測試類定義如下:
public class TestMyQueue {
public static void main(String[] args) throws Exception {
MyQueue queue = new MyQueue(5);
queue.put("A");
queue.put("B");
queue.put("C");
queue.put("D");
queue.put("E");
System.out.println("主線程queue : " + queue);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
queue.put("F");
queue.put("G");
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
queue.take();
Thread.sleep(1000);
queue.take();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "t2");
t1.start();
Thread.sleep(1000);
t2.start();
Thread.sleep(5000);
List<Object> elements = queue.getQueueList();
for(Object obj : elements) {
System.out.print(obj.toString() + " ");
}
}
}
該測試類除了main函數所在的主線程之外還存在兩個子線程t1,t2。線程t1負責向容器大小爲5的隊列容器放入"F"和"G"元素,線程t2則負責向隊列移除頭部節點。
輸出結果如下:
主線程queue : com.springchang.threadcore.celection.MyQueue@49476842
C D E F G