采用MogoDB生成ID的策略

来源:互联网 发布:近代报刊数据库爱如深 编辑:程序博客网 时间:2024/06/03 14:39
/**
 * 采用MogoDB生成ID的策略
 * 最终生成ID是24位16进制的字符串
 * 构成:8位时间+6位机器码+4位进程号+6位随机数
 * @author Rain
 *
 */
public class IDGen {

private static Logger logger  = Logger.getLogger(IDGen.class);
private static AtomicInteger nextInc = new AtomicInteger( (new java.util.Random()).nextInt() );
private static final int genMachine;

public static void main(String[] args) throws Exception{
System.out.println(IDGen.nextId()+"===>"+nextInc.getAndIncrement());
Thread.sleep(2000);
System.out.println(IDGen.nextId()+"==>"+nextInc.getAndIncrement());
}

static{
        try {
            // build a 2-byte machine piece based on NICs info
            int machinePiece;
            {
                try {
                    StringBuilder sb = new StringBuilder();
                    Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
                    while ( e.hasMoreElements() ){
                        NetworkInterface ni = e.nextElement();
                        sb.append( ni.toString() );
                    }
                    machinePiece = sb.toString().hashCode() << 16;
                } catch (Throwable e) {
                    // exception sometimes happens with IBM JVM, use random
                   // logger.log(Level.WARNING, e.getMessage(), e);
                    machinePiece = (new Random().nextInt()) << 16;
                }
                //logger.fine( "machine piece post: " + Integer.toHexString( machinePiece ) );
            }


            // add a 2 byte process piece. It must represent not only the JVM but the class loader.
            // Since static var belong to class loader there could be collisions otherwise
            final int processPiece;
            {
                int processId = new java.util.Random().nextInt();
                try {
                    processId = java.lang.management.ManagementFactory.getRuntimeMXBean().getName().hashCode();
                }
                catch ( Throwable t ){
                }


                ClassLoader loader = IDGen.class.getClassLoader();
                int loaderId = loader != null ? System.identityHashCode(loader) : 0;


                StringBuilder sb = new StringBuilder();
                sb.append(Integer.toHexString(processId));
                sb.append(Integer.toHexString(loaderId));
                processPiece = sb.toString().hashCode() & 0xFFFF;
                logger.info( "process piece: " + Integer.toHexString( processPiece ) );
            }


            genMachine = machinePiece | processPiece;
            logger.info( "machine : " + Integer.toHexString( genMachine ) );
        }
        catch ( Exception e ){
            throw new RuntimeException( e );
        }


    
}

public static String nextId(){
byte toByteArray[] = new byte[12];
    ByteBuffer bb = ByteBuffer.wrap( toByteArray );
    //by default BB is big endian like we need
    bb.putInt((int)(System.currentTimeMillis()/1000) );
    bb.putInt(genMachine);
    bb.putInt(nextInc.getAndIncrement());
    final StringBuilder buf = new StringBuilder(24);
    for(final byte b : toByteArray) {
       buf.append(String.format("%02x", b & 0xff));
    }
    return buf.toString();
}



}
0 0
原创粉丝点击