Skip to content

Commit

Permalink
polish alibaba#942, improve stack in ThreadLocalWatch.
Browse files Browse the repository at this point in the history
  • Loading branch information
hengyunabc committed Nov 20, 2019
1 parent 107da67 commit 24c4bcb
Showing 1 changed file with 52 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package com.taobao.arthas.core.util;

import java.util.Stack;

/**
* 简单的调用计时器。
* Created by vlinux on 16/6/1.
*
* @author vlinux 16/6/1.
* @author hengyunabc 2016-10-31
*/
public class ThreadLocalWatch {

private final ThreadLocal<Stack<Long>> timestampRef = new ThreadLocal<Stack<Long>>() {
private final ThreadLocal<LongStack> timestampRef = new ThreadLocal<LongStack>() {
@Override
protected Stack<Long> initialValue() {
return new Stack<Long>();
protected LongStack initialValue() {
return new LongStack(1024 * 4);
}
};

Expand All @@ -30,8 +29,52 @@ public double costInMillis() {
return (System.nanoTime() - timestampRef.get().pop()) / 1000000.0;
}

public void clear() {
timestampRef.remove();
}
/**
*
* <pre>
* 一个特殊的stack,为了追求效率,避免扩容。
* 因为这个stack的push/pop 并不一定成对调用,比如可能push执行了,但是后面的流程被中断了,pop没有被执行。
* 如果不固定大小,一直增长的话,极端情况下可能应用有内存问题。
* 如果到达容量,pos会重置,循环存储数据。所以使用这个Stack如果在极端情况下统计的数据会不准确,只用于monitor/watch等命令的计时。
*
* </pre>
*
* @author hengyunabc 2019-11-20
*
*/
static class LongStack {
private long[] array;
private int pos = 0;
private int cap;

public LongStack(int maxSize) {
array = new long[maxSize];
cap = array.length;
}

public int size() {
return pos;
}

public void push(long value) {
if (pos < cap) {
array[pos++] = value;
} else {
// if array is full, reset pos
pos = 0;
array[pos++] = value;
}
}

public long pop() {
if (pos > 0) {
pos--;
return array[pos];
} else {
pos = cap;
pos--;
return array[pos];
}
}
}
}

0 comments on commit 24c4bcb

Please sign in to comment.