我的问题是:
我有课:
public class AtomicStringBuilder {
private final AtomicReference<StringBuilder> sbRef;
}
我需要同时原子地向 StringBuilder 添加新字符。但问题是,这个对象中只能有最后 128 个字符。我不能使用 StringBuffer,因为操作应该是非阻塞的。
所以,有两个操作:
首先:检查 StringBuilder 是否已经有 128 个字符。
第二:如果没有 -> 添加新字符,如果有 -> 删除第一个字符并添加新字符。
有没有办法使这两个或三个操作原子化?
我做了这个方法,但它不起作用:
public void append(String string) {
this.sbRef.getAndUpdate(ref -> {
if (ref.length() < 128) {
ref.append(string);
} else {
ref.append(string).delete(0, ref.length() - 128);
}
return ref;
});
}
为了测试我创建了这个方法:
public void test() {
AtomicStringBuilder atomicStringBuilder = new AtomicStringBuilder();
Random random = new Random();
Stream<Integer> infiniteStream = Stream.iterate(0, i -> random.nextInt(10));
infiniteStream.parallel()
.limit(100000)
.forEach(integer -> atomicStringBuilder.append(String.valueOf(integer)));
assertEquals(128, atomicStringBuilder.getSb().get().length());
}
这不是一个真正的问题,我可以用其他任何可行的方法来更改 AtomicReference。任务是创建无锁且没有竞争条件的操作