环境:
windows7 64bit
jdk 1.6.0_24 64bit
cpu:i5-3210m@2.5G
内存:6G
因为工作中需要一个线程安全的Id生成器,然后不是云环境,就没必要用uuid,而且uuid性能也不怎么样,消耗也比较大,所以就自己实现了一个简单的Id生成器。然后就想到了用AtomicInteger,顺便就测一下它的性能,跟普通的同步方法相比。
写了两个类,MidFactory是单列的Id生成器工厂,里面用AtomicInteger来实现线程安全。testAtom是主类(不好意思,命名不规范,懒得改了)也是普通的synchronized方法类,开始用并发9999个线程测试,结果如下
0
after:9999
time cost:837
time cost:0
after:9999
task2:874
可以看到相差很小
然后用99999个线程并发,结果
0
after:99999
time cost:8464
after:99999
task2:8560
结果相差大概100毫秒,可见性能提升不是很明显。
我觉得至少应该有30%的提升,才能算性能有明显差别吧,然后我也懒得做统计平均分析了,有兴趣的可以用我的代码试试看。
代码:
testAtom
package test;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;
public class testAtom {
private AtomicInteger count=new AtomicInteger(0);
private MidFactory mf;
private int index=0;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testAtom ta=new testAtom();
long time1=Calendar.getInstance().getTimeInMillis();
/*try {
ta.init();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
long time2=Calendar.getInstance().getTimeInMillis();
System.out.println("time cost:"+(time2-time1));
try {
ta.init2();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void init() throws InterruptedException{
mf=MidFactory.getInstance();
System.out.println(mf.currentId());
Thread t=null;
for(int i=0;i<99999;i++){
t=new Thread(new Task());
t.start();
t.join();
}
System.out.println("after:"+mf.currentId());
}
private void init2() throws InterruptedException{
Thread t=null;
long t1=Calendar.getInstance().getTime().getTime();
for(int i=0;i<99999;i++){
t=new Thread(new Increment());
t.start();
t.join();
}
long t2=Calendar.getInstance().getTimeInMillis();
System.out.println("after:"+index);
System.out.println("task2:"+(t2-t1));
}
private synchronized int getAndAdd(){
return index++;
}
class Task implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
mf.getMid();
}
}
class Increment implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
getAndAdd();
}
}
}
MidFactory:
package test;
import java.util.concurrent.atomic.AtomicInteger;
public class MidFactory {
private static MidFactory mf;
private AtomicInteger ai=new AtomicInteger(0);
private MidFactory(){
}
public static MidFactory getInstance(){
if(mf==null){
mf=new MidFactory();
}
return mf;
}
public int getMid(){
if(ai.intValue()==Integer.MAX_VALUE){
ai.set(0);
}
return ai.getAndIncrement();
}
public int currentId(){
return ai.intValue();
}
}