java安全对象线程安全的快照

时间:2012-08-09 07:20:58

标签: java multithreading backup

我有一台服务器存储客户端的数据。 每个客户端都在自己的线程中工作,并且有一个数据对象 这个数据对象是一个自定义类,我们调用的是包含非自然数据的Data.java,这可能是一些字节,但通常来自大约100kb <1。数据&lt; 2MB。
现在我有一个备份线程,遍历客户端列表,使用Xstream将其数据对象解析为xml并将其存储在数据库中。
但这样安全吗? 如果客户端正在进行操作,在备份数据时更改数据(假设客户端每0.1秒发送一次请求,并且某些请求可能会在几秒钟内持续更改数据,那么此数据可能会损坏)。
什么是一个好方法呢?

1 个答案:

答案 0 :(得分:2)

每当您更改或阅读对象时,都可以使用synchronizedLock锁定对象。我还会使用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();
       }
    }