我有一台服务器存储客户端的数据。
每个客户端都在自己的线程中工作,并且有一个数据对象
这个数据对象是一个自定义类,我们调用的是包含非自然数据的Data.java,这可能是一些字节,但通常来自大约100kb <1。数据&lt; 2MB。
现在我有一个备份线程,遍历客户端列表,使用Xstream将其数据对象解析为xml并将其存储在数据库中。
但这样安全吗?
如果客户端正在进行操作,在备份数据时更改数据(假设客户端每0.1秒发送一次请求,并且某些请求可能会在几秒钟内持续更改数据,那么此数据可能会损坏)。
什么是一个好方法呢?
答案 0 :(得分:2)
每当您更改或阅读对象时,都可以使用synchronized
或Lock
锁定对象。我还会使用boolean dirty;
标志,只要你改变它就会设置为true
。这样,您的后台线程只需要保存已更改的对象。
由于客户端可能会在很长一段时间内更改数据,我会考虑使用lock.tryLock()
,它允许您尝试获取锁定而不会阻塞,因此线程仍可“备份”不是锁定。您可以随时重新尝试下一个周期。
一个例子
class Data{
final Lock lock = new ReentrantLock();
boolean dirty = false;
public void setSomething(String a) {
lock.lock();
try {
// modify the Data
dirty = true;
} finally {
lock.unlock();
}
}
public void backupData(Backup backup) {
if (!lock.tryLock()) return;
try {
if (!dirty) return;
backup.for(this);
dirty = false;
} finally {
lock.unlock();
}
}