假设我有一个指向对象列表的AtomicReference
:
AtomicReference<List<?>> batch = new AtomicReference<List<Object>>(new ArrayList<Object>());
线程 A 向此列表添加元素:batch.get().add(o);
稍后,线程 B 获取该列表并将其存储在数据库中,例如:insertBatch(batch.get());
在写入(线程 A)和读取(线程 B)时,我需要进行额外的同步以确保线程 B 以与线程 A 留下的方式查看列表,还是原子引用已经处理了这个问题?换句话说:如果我有一个对可变对象的原子引用,并且一个线程更改该对象,其他线程会立即看到此更改吗?
编辑:
也许需要一些示例代码:
public void process(Reader in) throws IOException {
List<Future<AtomicReference<List<Object>>>> tasks = new ArrayList<Future<AtomicReference<List<Object>>>>();
ExecutorService exec = Executors.newFixedThreadPool(4);
for (int i = 0; i < 4; ++i) {
tasks.add(exec.submit(new Callable<AtomicReference<List<Object>>>() {
@Override public AtomicReference<List<Object>> call() throws IOException {
final AtomicReference<List<Object>> batch = new AtomicReference<List<Object>>(new ArrayList<Object>(batchSize));
Processor.this.parser.parse(in, new Parser.Handler() {
@Override public void onNewObject(Object event) {
batch.get().add(event);
if (batch.get().size() >= batchSize) {
dao.insertBatch(batch.getAndSet(new ArrayList<Object>(batchSize)));
}
}
});
return batch;
}
}));
}
List<Object> remainingBatches = new ArrayList<Object>();
for (Future<AtomicReference<List<Object>>> task : tasks) {
try {
AtomicReference<List<Object>> remainingBatch = task.get();
remainingBatches.addAll(remainingBatch.get());
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof IOException) {
throw (IOException)cause;
}
throw (RuntimeException)cause;
}
}
// these haven't been flushed yet by the worker threads
if (!remainingBatches.isEmpty()) {
dao.insertBatch(remainingBatches);
}
}
这里发生的是我创建了四个工作线程来解析一些文本(这是
process()
方法中的Reader in
参数)。每个工作线程将其解析的行保存在一个批次中,并在批次满时刷新该批次 (dao.insertBatch(batch.getAndSet(new ArrayList<Object>(batchSize)));
)。由于文本中的行数不是批处理大小的倍数,因此最后的对象会被放入未刷新的批次中,因为它不是满的。因此,这些剩余的批次由主线程插入。
我使用
AtomicReference.getAndSet()
用空批次替换完整批次。这个程序在线程方面是正确的吗?
AtomicReference.getAndSet()
来用一个新的空批次替换整个批次。我还需要额外的同步吗? - Jan Van den boschAtomicReference
。 - Tudorvolatile
变量而不是AtomicReference
。 - Alex D