`
teasp
  • 浏览: 61555 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

错误的序列号生成器

阅读更多
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());
            } 
        } 
    }
}

 

0
4
分享到:
评论

相关推荐

    cod4序列号生成器

    cod4序列号生成器 cod4序列号生成器

    数据库序列号生成器

    数据库序列号生成器是一种工具,通常用于为数据库中的记录生成唯一的标识符,这些标识符可以作为主键,确保数据的唯一性和完整性。在数据库设计中,主键是表中一个或一组字段,其值能够唯一地标识每条记录。序列号...

    Nero Burning Rom 序列号生成器

    然而,"Nero Burning Rom 序列号生成器"涉及的话题较为敏感,因为这可能指的是一个用于生成非法或假冒软件序列号的工具,这违反了软件版权法律。 首先,让我们明确一点:合法使用软件是每个用户的义务,尊重知识...

    易语言序列号生成器

    易语言序列号生成器源码,序列号生成器,十六进制到十进制,十进制到十六进制,序列号显示,序列号算法,序列号反算,读取授权文件,秘密,wvsprintfA,StrToIntExA

    虚拟机序列号生成器.

    虚拟机序列号生成器.rar

    卡巴斯基序列号生成器

    卡巴斯基序列号生成器

    adobe-dreamwear cs4序列号生成器

    【标题】"adobe-dreamwear cs4序列号生成器"所涉及的知识点主要集中在Adobe Dreamweaver CS4这款软件的授权与激活机制上。Adobe Dreamweaver是Adobe公司开发的一款专业级网页设计和开发工具,它融合了视觉设计与代码...

    序列号生成器

    ### 序列号生成器实现解析 #### 一、概述 本文将深入解析一个Java实现的序列号生成器,该生成器主要用于在分布式系统中生成唯一标识符(ID)。通过分析其核心方法`nextId()`及辅助方法,我们将了解它是如何确保在...

    web storm 序列号生成器

    web storm 序列号生成器, 破解, 支持当前最新的WebStorm3.03, 3.03版本支持NodeJS的开发. 非常好用的JavaScript的开发工具.

    虚拟化硬件序列号生成器匿名者 v1.5.zip

    系统硬盘序列号 网卡MAC 主板信息 支持Windows10 1809 1903 1909 2004 20h2 21h1 使用方法就是依次输入1 2 3就行 重启不会自动恢复 : 随机化注册表和重置网卡数据 重启会自动恢复 : 加载匿名驱动 建议配合影子系统...

    软件序列号生成器.rar

    软件序列号生成器,通取物理地址,实现对MAC地址的绑定。加密好工具。

    Steelray Project Viewer序列号生成器

    Steelray Project Viewer序列号生成器noy-steelray.project.viewer.keygen.jar 支持5.0以上版本,其他版本未测试 运行需安装jdk、jre 另,内含多个可用的license

    eset序列号产生器

    eset 序列号生成器eset 序列号生成器eset 序列号生成器eset 序列号生成器

    vmware workstation 10 序列号生成器

    在描述中提到的“vmware workstation 10 序列号生成器”是指一种工具,通常这类工具是非官方的,目的是为了生成可以激活VMware Workstation 10的序列号。然而,值得注意的是,使用这种序列号生成器是违反VMware的...

    Balsamiq.Mockups.v2.2.3 包括序列号生成器

    使用序列号生成器违反了软件的许可协议,因为这本质上是逃避了购买授权的必要性。合法使用Balsamiq Mockups应通过官方渠道购买并激活,支持软件开发者的工作。 **3. 命令行运行** 描述中提到了在命令行环境下运行`...

    C#自动生成序列号 源码

    二、C#中的随机数生成器 生成序列号的一个基本方法是使用C#的`Random`类。这个类可以生成伪随机数,但为了确保序列号的独特性,我们可以使用`Guid`类,它能生成全局唯一的标识符。 三、`Guid`类的应用 `Guid`(全局...

    汉语大辞典5.87序列号生成器

    完全意义上的 汉语大辞典5.87序列号生成程序,不是程序的破解,真正的注册序列号,一台机器对应很多序列号,选择一个输入即可完美注册

    eclipse序列号生成器

    【标题】"eclipse序列号生成器"涉及的是软件授权和Eclipse集成开发环境(IDE)的相关知识。Eclipse是一款开源、跨平台的Java IDE,广泛用于Java应用程序的开发,同时也支持其他编程语言如C++、Python等。然而,这里...

    Delphi XE5完美破解含序列号生成器

    经过多次尝试和搜索,经本人验证确实可以完美破解Delphi和C++ Builder XE5的破解工具和序列号生成器。

    VMware workstation 7.1.4序列号生成器

    VMware workstation 7.1.4序列号生成器,自己使用没有问题,特别推荐

Global site tag (gtag.js) - Google Analytics