1. 程式人生 > >實現一個固定大小的安全佇列。

實現一個固定大小的安全佇列。

-----記錄坑自己的邏輯錯誤,一定不要有else。

---想當然的認為滿了就不新增,滿了是等待後續再次新增,需要恢復到原來的樣子。

 

package com.mobile263;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/***
 * 實現功能:實現一個固定大小的安全佇列。
 * @author ying
 *
 */
public class SafeQueue {

	//實現步驟:
	// 1.要求大小固定
	// 2,佇列可丟擲可壓入
	// 3 需要安全,即佇列滿了,不能再壓入,
	// 4 佇列空的,即不能彈出.
	// 5 在壓入得時候不能取,否則髒讀
	
	private int lensize = 8;
	private List<String> arryList = new ArrayList<String>();
//	final CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<String>(arryList);
//	private Queue<String> queue = new LinkedList<String>();
	
	private Object lockObject = new Object();
	
	public void put(String data) {
		
		synchronized (lockObject) {
			
			try {
				if(arryList.size() == lensize) {
					System.out.println("佇列滿了,請等待...");
					lockObject.wait();		
				}
				
				//這個地方不需要else,讓執行緒恢復到原來的樣子,依然能夠加入。
				arryList.add(data);
				System.out.println("壓入的資料為:" + data);
				lockObject.notifyAll();
				
			} catch (Exception e) {
				e.printStackTrace();
			}
	
		}

	}
	
	
	public String get () {
		synchronized (lockObject) {
			try {
				if(arryList.isEmpty()) {
					System.out.println("佇列是空的,請等待....");
					lockObject.wait();
				}
				//這個地方不需要else,讓執行緒恢復到原來的樣子,依然能夠刪除。
					String data =  arryList.get(0);
					Iterator<String> iter = arryList.iterator();
				    while (iter.hasNext()) {
				        String item = iter.next();
				        if (item.equals(data)) {
				            iter.remove();
				        }
				    }
					
					lockObject.notifyAll();
					System.out.println("獲取的資料為:" + data);
					
					return data;
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return null;
	}
	
	public static void main(String[] args) {
		
		
		SafeQueue queue = new SafeQueue();
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				queue.put("1");
				queue.put("2");
				queue.put("3");
				queue.put("4");
				queue.put("5");
				queue.put("6");
				queue.put("7");
				
			}
		},"t1");
		

		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				queue.get();
				queue.get();
				queue.get();
				queue.get();
				queue.get();
				queue.get();
				queue.get();

				
			}
		},"t2");
		
		t2.start();
		
		
		try {
			Thread.sleep(1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		t1.start();
		
		
		
	}
}