1. 程式人生 > >Java多執行緒之模擬一個阻塞佇列

Java多執行緒之模擬一個阻塞佇列

import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;

public class MyQueue {


    private final LinkedList<Object> list = new LinkedList<>();

    //需要一個計數器,統計加入List集合元素的個數

    private AtomicInteger count = new AtomicInteger(0);

    //需要指定上限和下限

    private int minSize = 0
; private int maxSize ; //建立queue時指定最大長度 public MyQueue(int size){ this.maxSize=size; } //初始化一個物件,用於加鎖 private Object lock = new Object(); public void put(Object obj){ synchronized (lock){ while(count.get() == this.maxSize){ try { lock
.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } list.add(obj); //計數器加一 count.incrementAndGet(); System.out.println("新新增的元素為:"+obj); //通知其他執行緒 lock.notify(); } } public
Object take(){ Object ret =null; synchronized (lock){ //注意這裡不使用list.getSize() while(count.get()==this.minSize){ try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //移除元素並返回 ret =list.removeFirst(); count.decrementAndGet(); lock.notify(); } return ret ; } public int getSize(){ return this.count.get(); } public static void main(String[] args) { final MyQueue mq = new MyQueue(5); mq.put("a"); mq.put("b"); mq.put("c"); mq.put("d"); mq.put("e"); System.out.println("當前容器的長度:"+mq.getSize()); new Thread(new Runnable() { @Override public void run() { //此時容器已經滿了,會阻塞 mq.put("f"); mq.put("g"); System.out.println(Thread.activeCount()); } }).start(); // 休眠兩秒鐘 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(new Runnable() { @Override public void run() { //從容器裡面拿元素,同時喚醒新增元素的執行緒 Object o1= mq.take(); System.out.println("當前移除的元素"+o1); Object o2= mq.take(); System.out.println("當前移除的元素"+o2); } }).start(); } }

列印結果為

新新增的元素為:a
新新增的元素為:b
新新增的元素為:c
新新增的元素為:d
新新增的元素為:e
當前容器的長度:5
//這裡停頓兩秒鐘,說明第一個新增元素的執行緒還沒有執行,在第二個執行緒執行完後,才會執行第一個執行緒
新新增的元素為:f
當前移除的元素a
當前移除的元素b
新新增的元素為:g
3