final int threadC = 300;
final int loopC = 1000;
//final Set<Long> idCounter = Sets.newConcurrentHashSet();
final List<Long> idCounter = new ArrayList<>(threadC*loopC);
final IdWorker idWorker = new IdWorker(0, 0);
final CountDownLatch latch = new CountDownLatch(threadC*loopC);
for (int j=0; j<threadC; j++)
{
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < loopC; i++) {
long id = idWorker.nextId();
idCounter.add(id);
latch.countDown();
}
}
}).start();
}
long st = System.currentTimeMillis();
latch.await();
long en = System.currentTimeMillis();
System.out.println("idCounter:"+idCounter.size()+",T:"+(en-st));
new ArrayList<>(),执行结果:你猜?java.lang.ArrayIndexOutOfBoundsException: 10 ,应该是动态扩容线程不安全造成。
new ArrayList<>(threadC*loopC),执行结果:idCounter:285572,T:103 ,设置固定容量后,不抛异常了。从数据看,好明显线程不安全,导致统计数据不正确。
Lists.newCopyOnWriteArrayList() ,执行结果:idCounter:300000,T:54015,线程安全,但执行性能巨差。
最后出大杀器,Sets.newConcurrentHashSet(); 执行结果:idCounter:300000,T:88,线程安全,性能很好。
--------------------
调整下参数 final int threadC = 1000; final int loopC = 10000;
idCounter:10000000,T:6409
6秒生成了一千万个不重复id,是不是很牛?
再调整下参数,充分利用下机器资源,性能大幅提高 final int threadC = 9000; final int loopC = 1000;
idCounter:9000000,T:687 700毫秒生成了900万个不重复id,牛逼大了!