public class IncorrectSerialGenerator {
public static final int MAX_VAL = 999;
public static final int R_NUM = getRNum(MAX_VAL);
private static AtomicInteger val = new AtomicInteger(0);
/* private static AtomicReference<AtomicInteger> ref = new AtomicReference<AtomicInteger>(new AtomicInteger(0));
public static int getSerialNo() {
AtomicInteger old = ref.get();
int serialNo = old.getAndIncrement();
while (serialNo > MAX_VAL) {
AtomicInteger update = new AtomicInteger(0);
ref.compareAndSet(old, update);
old = ref.get();
serialNo = old.getAndIncrement();
}
return serialNo;
}*/
public static int getSerialNo() {
int serialNo = val.getAndIncrement();
if (serialNo > MAX_VAL) {
val.set(0); //原子操作
serialNo = val.getAndIncrement();//原子操作,但是两者一起就不是原子操作,存在线程安全问题
}
return serialNo;
}
/**
* 求整数有几位,如234是3位。
* @param i
* @return
*/
private static final int getRNum(int i) {
if (i < 0) {
throw new RuntimeException("Illegal arg i, i=" + i);
}
int div = i;
int num = 1;
div /= 10;
while (div > 0) {
div /= 10;
num++;
}
return num;
}
/**
* 获取序列号,该序列号为字符串表示,长度固定为序列号的最大长度,
* 如果长度不足,则在前面补0,比如"015"
* @return
*/
public static String getSerialNoInStr() {
int serialNo = getSerialNo();
int rnum = getRNum(serialNo);
StringBuilder sb = new StringBuilder();
for (int i=0; i<R_NUM-rnum; i++) {
sb.append("0");
}
return sb.append(serialNo).toString();
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
IncorrectSerialGenerator gen = new IncorrectSerialGenerator();
gen.test();
}
@Test
public void test() throws InterruptedException, ExecutionException {
//测10次
for (int t=0; t<10; t++) {
int taskNum = 1 + new Random().nextInt(19);
@SuppressWarnings("unchecked")
Future<Integer>[] fs = new Future[taskNum];
ExecutorService executor = Executors.newFixedThreadPool(taskNum);
for (int i=0; i<taskNum; i++) {
fs[i] = executor.submit(new Callable<Integer>() {
int sum = 0;
@Override
public Integer call() throws Exception {
for (int i=0; i<=MAX_VAL; i++) {
sum += getSerialNo();
// System.out.println(Thread.currentThread().getName() + " : " + sum);
}
return new Integer(sum);
}
});
}
int result = 0;
for (Future<Integer> future : fs) {
result += future.get();
}
int expect = 0;
for (int i=0; i<taskNum; i++) {
for (int j=0; j<=MAX_VAL; j++) {
expect += j;
}
}
Assert.assertEquals(expect, result);
System.out.println(taskNum + " : " + expect);
}
Random random = new Random();
for (int i=0; i<10000; i++) {
getSerialNoInStr();
if (random.nextInt(1000) < 9) {
System.out.println(getSerialNoInStr());
}
}
}
}