原码笔记

原码笔记

分享与ChatGPT的一次对话

小诸哥 0

分享与ChatGPT的一次对话

最近ChatGPT大火, 相比很多人工智障,这个是真的智能。有了它,感觉可以不用面向谷歌或百度编程了。 分享下ChatGPT帮我改代码的一场对话

场景

业务需要生成递增id返回给业务使用,同时需要入库。为了让返回和入库分开,这里用redis.incr来生成一个num值, 业务直接返回,数据库做异步入库。 同时考虑到一条一条生成太慢了, 所以需要做预分配。

昨天写完了主要逻辑,本来今天想要再测试优化一波,突然想到能不能测试下ChatGPT,毕竟说的那么牛逼, 于是就有了这篇文章。

对话

image.png 帮我看下这段代码有没有问题

Map<Integer, Counter> counterMap = new ConcurrentHashMap<>();
private long fetchNextNum(int tableNum) {
        Counter counter = counterMap.get(tableNum);
        if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
            counter = buildNewCounter(tableNum, 100);
        }
        long nextId = counter.getCurrent().incrementAndGet();
        if (nextId > counter.getMax().get()) {
            //号码已用完, 尝试重新获取
            return fetchNextNum(tableNum);
        }
        return nextId;
    }

private Counter buildNewCounter(int tableNum, int size) {
    String key = String.format("short_url_id_%s", String.valueOf(tableNum));
    synchronized (this) {
        Counter counter = counterMap.get(tableNum);
        if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
            //counter不存在或已耗尽, 申请新的资源
           Long max = this.jedisCacheManager.incrBy(key, size);
           counter = new Counter(new AtomicLong(max - size), new AtomicLong(max));
           counterMap.put(tableNum, counter);
       }
       return counter;
    }
}
@Data
class Counter {
    private AtomicLong current;
    private AtomicLong max;

    public Counter(AtomicLong current, AtomicLong max) {
        this.current = current;
        this.max = max;
    }
}
复制代码

image.png

image.png 这段代码有问题吗?

Map<Integer, Counter> counterMap = new ConcurrentHashMap<>();
Map<Integer, Object> lockMap = new ConcurrentHashMap<>();

private Counter buildNewCounter(int tableNum, int size) {
    String key = String.format("short_url_id_%s", String.valueOf(tableNum));
    //这里改成了分段锁
    synchronized (lockMap.computeIfAbsent(tableNum, t -> new Object())) {
        Counter counter = counterMap.get(tableNum);
        if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
            //counter不存在或已耗尽, 申请新的资源
            Long max = this.jedisCacheManager.incrBy(key, size);
            counter = new Counter(new AtomicLong(max - size), new AtomicLong(max));
            counterMap.put(tableNum, counter);
        }
        return counter;
    }
}
复制代码

image.png

image.png 这样呢?

Map<Integer, Counter> counterMap = new ConcurrentHashMap<>();
Map<Integer, ReentrantLock> lockMap = new ConcurrentHashMap<>();

private Counter buildNewCounter(int tableNum, int size) {
    String key = String.format("short_url_id_%s", String.valueOf(tableNum));
    //使用ReentrantLock替代synchronized
    ReentrantLock lock = lockMap.computeIfAbsent(tableNum, t -> new ReentrantLock());
    lock.lock();
    try {
        Counter counter = counterMap.get(tableNum);
        if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
            //counter不存在或已耗尽, 申请新的资源
            Long max = this.jedisCacheManager.incrBy(key, size);
            counter = new Counter(new AtomicLong(max - size), new AtomicLong(max));
            counterMap.put(tableNum, counter);
        }
        return counter;
    } finally {
        lock.unlock();
    }
}
复制代码

image.png

image.png 那这样呢

Map<Integer, Counter> counterMap = new ConcurrentHashMap<>();
Map<Integer, ReentrantLock> lockMap = new ConcurrentHashMap<>();

private long fetchNextNum(int tableNum) {
    Counter counter = counterMap.get(tableNum);
    if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
        counter = buildNewCounter(tableNum, 100);
    }
    long nextId = counter.getCurrent().incrementAndGet();
    if (nextId > counter.getMax().get()) {
        // 号码已用完, 尝试重新获取
        while (true) {
            counter = buildNewCounter(tableNum, 100);
            nextId = counter.getCurrent().incrementAndGet();
            if (nextId <= counter.getMax().get()) {
                return nextId;
            }
        }
    }
    return nextId;
}

private Counter buildNewCounter(int tableNum, int size) {
    String key = String.format("short_url_id_%s", String.valueOf(tableNum));
    ReentrantLock lock = lockMap.computeIfAbsent(tableNum, t -> new ReentrantLock());
    lock.lock();
    try {
        Counter counter = counterMap.get(tableNum);
        if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
            //counter不存在或已耗尽, 申请新的资源
            Long max = this.jedisCacheManager.incrBy(key, size);
            counter = new Counter(new AtomicLong(max - size), new AtomicLong(max));
            counterMap.put(tableNum, counter);
        }
        return counter;
    } finally {
        lock.unlock();
    }
}

复制代码

image.png

Map<Integer, Counter> counterMap = new ConcurrentHashMap<>();
Map<Integer, StampedLock> lockMap = new ConcurrentHashMap<>();

private long fetchNextNum(int tableNum) {
    Counter counter = counterMap.get(tableNum);
    if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
        counter = buildNewCounter(tableNum, 100);
    }
    long nextId = counter.getCurrent().incrementAndGet();
    if (nextId > counter.getMax().get()) {
        // 号码已用完, 尝试重新获取
        while (true) {
            counter = buildNewCounter(tableNum, 100);
            nextId = counter.getCurrent().incrementAndGet();
            if (nextId <= counter.getMax().get()) {
                return nextId;
            }
        }
    }
    return nextId;
}

private Counter buildNewCounter(int tableNum, int size) {
    String key = String.format("short_url_id_%s", String.valueOf(tableNum));
    StampedLock lock = lockMap.computeIfAbsent(tableNum, t -> new StampedLock());
    long stamp = lock.writeLock();
    try {
        Counter counter = counterMap.get(tableNum);
        if (counter == null || counter.getCurrent().get() > counter.getMax().get()) {
            //counter不存在或已耗尽, 申请新的资源
            Long max = this.jedisCacheManager.incrBy(key, size);
            counter = new Counter(new AtomicLong(max - size), new AtomicLong(max));
            counterMap.put(tableNum, counter);
        }
        return counter;
    } finally {
        lock.unlock(stamp);
    }
}
复制代码

image.png

image.png

在我的再三要求下,ChatGPT终于承认这是一段优秀的代码, 哈哈[手打狗头]

总结

ChatGPT有时候会说话说到一半就没了,但这不妨碍它是一款非常优秀非常牛逼的AI对话机器人, 是真得能给出非常有用的建议。 做的真不错。

标签: 分享 ChatGPT 一次 对话

上一篇

下一篇ChatGPT OpenAI聊天机器人