冲杯茶喝 2012-07-02 17:28
浏览 204
已采纳

贴一段代码,一个id的生成器,求解

[code="java"]
/*

  • This file is part of aion-unique . *
  • aion-unique is free software: you can redistribute it and/or modify
  • it under the terms of the GNU General Public License as published by
  • the Free Software Foundation, either version 3 of the License, or
  • (at your option) any later version. *
  • aion-unique is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  • GNU General Public License for more details. *
  • You should have received a copy of the GNU General Public License
  • along with aion-unique. If not, see http://www.gnu.org/licenses/. */ package com.aionemu.chatserver.utils;

import java.util.BitSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**

  • Simplified version of idfactory
  • @author ATracer
    */
    public class IdFactory
    {
    private final BitSet idList = new BitSet();
    private final ReentrantLock lock = new ReentrantLock();
    private AtomicInteger nextMinId = new AtomicInteger(1);

    protected static IdFactory instance = new IdFactory();

    public int nextId()
    {
    try
    {
    lock.lock();
    int id = idList.nextClearBit(nextMinId.intValue());
    idList.set(id);
    nextMinId.incrementAndGet();
    return id;
    }
    finally
    {
    lock.unlock();
    }
    }

    public static IdFactory getInstance()
    {
    return instance;
    }

    public static void main(String[] xiaoe)
    {
    BitSet idList = new BitSet();
    for (int i = 0; i < 100; i++)
    System.out.println(idList.nextClearBit(i));
    }

}

[/code]
我觉得有两个问题:
1. 这里既然已经用锁同步了,就可以不用atomic类
2. BitSet有点画蛇添足的味道

不知道作者为何要这么设计,求解。谁能指点下这么写的好处。

  • 写回答

3条回答

  • _1_1_7_ 2012-07-03 08:44
    关注

    [code="java"]public class IdFactory {
    private final ReentrantLock lock = new ReentrantLock();
    private volatile int id = 0;
    private static final IdFactory instance = new IdFactory();

    private IdFactory() {
    }
    
    public int nextId() {
        try {
            lock.lock();
            id++;
            return id;
        } finally {
            lock.unlock();
        }
    }
    
    public static IdFactory getInstance() {
        return instance;
    }
    
    static class TestThread extends Thread {
        ArrayList<Integer> idList = new ArrayList<Integer>();
    
        public void run() {
            IdFactory fac = IdFactory.getInstance();
            for (int i = 0; i < 10000; i++) {
                idList.add(fac.nextId());
            }
        }
    }
    
    public static void main(String[] arg) throws Exception {
        TestThread t1 = new TestThread();
        TestThread t2 = new TestThread();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(t1.idList.size());
        System.out.println(t2.idList.size());
        t1.idList.removeAll(t2.idList);
        System.out.println(t1.idList.size());
        System.out.println(t2.idList.size());
    }
    

    }[/code]
    我这样写,效果应该一样吧!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料