1. 程式人生 > >java實現執行緒安全的棧(鏈式儲存)

java實現執行緒安全的棧(鏈式儲存)

package com.boco.stackTest.sxlTest;

import com.boco.stackTest.LinkStack;
import com.boco.stackTest.Stack;
import com.boco.stackTest.link.LinkNode;
import com.boco.stackTest.sxlTest.ConcurrentTest.ConcurrentTask;

public class Test {
	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//使用自己實現的棧進行初始化
		final Stack<Long> s = new LinkStack();
		//建立多個執行緒同時壓棧,64位JVM可以開到10000+,32位JVM可以開到2000~3000之間
		int threadNum = 2000;
		ConcurrentTask[] task = new ConcurrentTask[threadNum];
		long start = System.nanoTime();
		for (int i = 0; i < task.length; i++) {
			task[i] = new ConcurrentTask() {
				public void run() {
					LinkNode node = new LinkNode(1,"name");
					s.push(node);
				}
			};
		}
		new ConcurrentTest(task);
		long end = System.nanoTime();
		//列印所有執行緒的入棧時間
		System.out.println("total time: " + (end - start)/1.0e9);
		/*
		 * 測試時要保證下面列印的i和上面初始化的執行緒數threadNum一致,
		 * 因為如果是執行緒安全的棧,入棧和出棧的數目應該是一樣的。
		 * 如果要單獨測試上面的total time:時間,可以將下面的程式碼註釋掉進行測試。
		 */
		System.out.println("pop ------------------------------------");
		for (int i=1;;i++) {
			LinkNode l = s.pop();
			if(l == null)
				break;
			System.out.println(i + "	"+l.getKey()+"                " + l.getValue());
		}
	}

}
package com.boco.stackTest.sxlTest;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
  ConcurrentTask[] task = new ConcurrentTask[5];
  for(int i=0;i<task.length;i++){
  	   task[i] = new ConcurrentTask(){
 			public void run() {
 				System.out.println("==============");
 				
 			}};
  }
  new ConcurrentTest(task);
 * @author xueliang
 *
 */
public class ConcurrentTest {
	private CountDownLatch startSignal = new CountDownLatch(1);//開始閥門
	private CountDownLatch doneSignal = null;//結束閥門
	private CopyOnWriteArrayList<Double> list = new CopyOnWriteArrayList<Double>();
	private AtomicInteger err = new AtomicInteger();//原子遞增
	private ConcurrentTask[] task = null;
	
	public ConcurrentTest(ConcurrentTask... task){
		this.task = task;
		if(task == null){
			System.out.println("task can not null");
			System.exit(1);
		}
		doneSignal = new CountDownLatch(task.length);
		start();
	}
	/**
	 * @param args
	 * @throws ClassNotFoundException 
	 */
	private void start(){
		//建立執行緒,並將所有執行緒等待在閥門處
		createThread();
		//開啟閥門
		startSignal.countDown();//遞減鎖存器的計數,如果計數到達零,則釋放所有等待的執行緒
		try {
			doneSignal.await();//等待所有執行緒都執行完畢
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//計算執行時間
		getExeTime();
	}
	/**
	 * 初始化所有執行緒,並在閥門處等待
	 */
	private void createThread() {
		long len = doneSignal.getCount();
		for (int i = 0; i < len; i++) {
			final int j = i;
			new Thread(new Runnable(){
				public void run() {
					try {
						startSignal.await();//使當前執行緒在鎖存器倒計數至零之前一直等待
						long start = System.nanoTime();
						task[j].run();
						long end = System.nanoTime();
						double time = (end - start) / 1.0e6;
						list.add(time);
					} catch (Exception e) {
						err.getAndIncrement();//相當於err++
					} 
					doneSignal.countDown();
				}
			}).start();
		}
	}
	/**
	 * 計算平均響應時間
	 */
	private void getExeTime() {
		int size = list.size();
		List<Double> _list = new ArrayList<Double>(size);
		_list.addAll(list);
		Collections.sort(_list);
		double min = _list.get(0);
		double max = _list.get(size-1);
		double sum = 0L;
		for (Double t : _list) {
			sum += t;
		}
		double avg = sum/size;
		System.out.println("min: " + min);
		System.out.println("max: " + max);
		System.out.println("avg: " + avg);
		System.out.println("err: " + err.get());
	}
	
	public interface ConcurrentTask {
		void run();
	}

}

package com.boco.stackTest;

import java.util.Map;

import com.boco.stackTest.link.LinkNode;

/**
 * 實現執行緒安全的棧
 * @author Administrator
 *
 */
public class LinkStack implements Stack {
	
	/**
	 * 棧頂指標
	 */
	public LinkNode top = null;
	
	private int length=0;
	
	public LinkStack(){
        top = new LinkNode(0, "null");
    } 
	
	public LinkNode pop() {
		synchronized(this){
			top = top.getNext();
			length--;
			return top;
		}
	}

	public void push(LinkNode element) {
		synchronized(this){
			if(element != null){
				element.setNext(top);
             	top = element;
        		length++;
			}
		}
	}
	
    /**
     * 列印棧內元素
     * @param currentNode
     */
    public void printStack(){
    	LinkNode currentNode = top;
        if(currentNode != null){
        	System.out.println("===========================================================");
            while(currentNode != null){
                System.out.println("key="+currentNode.getKey()+"--name="+currentNode.getValue());
                currentNode = currentNode.getNext();
            }
        	System.out.println("===========================================================");
        }
        else{
            System.out.println("the stack is null");
        }
    }
    
    public int length(){
    	return length;
    }

}
package com.boco.stackTest;

import com.boco.stackTest.link.LinkNode;

public interface Stack<T> {
	/**
	 * 將元素壓入棧中
	 * @param string
	 */
	public void push(LinkNode string);
	/**
	 * 彈出棧頂元素
	 */
	public LinkNode pop();
	/**
	 * 列印當前棧中所有元素
	 */
	public void printStack();
	/**
	 * 返回當前棧中元素個數
	 * @return
	 */
	public int length();
}
package com.boco.stackTest.link;

public class LinkNode {
	 private int key = 0;
     private String value = null;
     private LinkNode next = null;
    
     public LinkNode(int key, String data){
         this.key = key;
         this.value = data;
         this.next = null;
     }
    
     public int getKey() {
         return key;
     }

     public void setKey(int key) {
         this.key = key;
     }


     public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public LinkNode getNext() {
         return next;
     }

     public void setNext(LinkNode next) {
         this.next = next;
     }
}