java實現執行緒安全的棧(鏈式儲存)
阿新 • • 發佈:2019-02-01
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;
}
}