AtomicInteger性能試験


環境:
windows 7 64 bit
jdk 1.6.0_24 64 bit
cpu:i [email protected]
メモリ:6 G
作業にはスレッドの安全なIdジェネレータが必要で、雲環境ではなく、uuidを使う必要がありません。また、uuidの性能もあまり良くなく、消耗も大きいので、簡単なIdジェネレータを自分で実現しました。そしてAtomicIntegerを使って、ついでにその性能を測ってみたいです。普通の同期方法と比べて。
二つの種類を書いていますが、MidFactoryは単一列のIdジェネレータ工場で、中はAtomicIntegerでスレッドの安全を実現します。testAtomはメインクラスです。(すみません、ネーミングが規範ではなく、変更がおっくうです。)も普通のsynchronizedメソッドクラスです。同時に9999スレッドのテストを開始しました。結果は以下の通りです。
0
after:9999
time cost:837


time cost:0
after:9999
task2:874
差が小さいのが見えます。
9999個のスレッドで同時進行した結果
0
after:99999
time cost:8464

after:99999
task2:8560
その結果、約100ミリ秒の差が見られますが、性能の向上はそれほど顕著ではありません。
少なくとも30%のアップグレードがあるべきだと思います。性能に明らかな差があると言えるでしょう。そして私も統計平均分析をするのがおっくうです。興味があるのはコードを使ってみてもいいです。
コード:
test Atom
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();
	}

}