最近ChatGPT大火, 相比很多人工智障,这个是真的智能。有了它,感觉可以不用面向谷歌或百度编程了。 分享下ChatGPT帮我改代码的一场对话。
场景
业务需要生成递增id返回给业务使用,同时需要入库。为了让返回和入库分开,这里用redis.incr来生成一个num值, 业务直接返回,数据库做异步入库。 同时考虑到一条一条生成太慢了, 所以需要做预分配。
昨天写完了主要逻辑,本来今天想要再测试优化一波,突然想到能不能测试下ChatGPT,毕竟说的那么牛逼, 于是就有了这篇文章。
对话
帮我看下这段代码有没有问题
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;
}
}
复制代码
这段代码有问题吗?
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;
}
}
复制代码
这样呢?
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();
}
}
复制代码
那这样呢
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();
}
}
复制代码
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);
}
}
复制代码
在我的再三要求下,ChatGPT终于承认这是一段优秀的代码, 哈哈[手打狗头]
总结
ChatGPT有时候会说话说到一半就没了,但这不妨碍它是一款非常优秀非常牛逼的AI对话机器人, 是真得能给出非常有用的建议。 做的真不错。
赏
版权声明:本站所有图片/内容除标明原创外,均来自网络转载,版权归原作者所有,如果有侵犯到您的权益,请联系本站删除,谢谢!