我有一个使用类似cron作业的应用程序来更新一组数据。更新过程每分钟发生一次,并且不会持续很长时间。 servlet将此数据集公开给用户。我的问题是在更新过程中,servlet请求应该阻塞并等待进程完成。
在底线我有这两个功能:
private void updateData() {
}
public List getData() {
}
第一个函数每分钟运行一次。第二个可以同时调用任意次数。当updateData运行时,所有getData调用都必须等待它完成。一个getData调用不应该阻止相同函数的后续调用。 updateData函数的优先级高于getData,即当要运行updateData时,它必须等待所有getData调用完成,但不允许新的调用启动。
我应该在这种情况下使用什么同步机制?我正在使用Java服务器,但我很想知道其他平台也存在哪些解决方案。
答案 0 :(得分:5)
您可以使用ReadWriteLock代替同步。
ReadWriteLock维护一对关联的锁,一个用于只读操作,另一个用于写入。只要没有写入器,读锁定可以由多个读取器线程同时保持。写锁是独占的。
public void updateData() {
lock.writeLock().lock();
try {
/* do stuff. */
} finally {
lock.writeLock().unlock();
}
}
public List getData() {
lock.readLock().lock();
try {
/* process/return data. */
} finally {
lock.readLock().unlock();
}
}
答案 1 :(得分:3)
看一下这篇文章:Read / Write Locks in Java
我在这个例子中可以看到的唯一缺点是notifyAll()唤醒所有等待的线程。 但是,它确实优先写入锁定请求。
答案 2 :(得分:0)
您需要同步数据访问权限。
public void updateData() {
synchronized (updateLock) {
/* do stuff. */
}
}
public List getData() {
List data;
synchronized (updateLock) {
data = getRealData();
}
/* process/return data. */
}
答案 3 :(得分:0)
CopyOnWriteArrayList或CopyOnWriteArraySet是值得关注的。在不经常更新的情况下,我一直在使用它们。