假设我有一堂课:
public class Chat {
private volatile ConcurrentLinkedQueue messages = new ConcurrentLinkedQueue();
// getter/setter for messages queue
}
我有一个后台线程,它将此类的一个实例作为参数:
Thread t = new Thread(new QueuePersister(messages));
t.start();
线程的任务是:
public class QueuePersister implements Runnable {
private volatile ConcurrentLinkedQueue messages = new ConcurrentLinkedQueue();
public QueuePersister(ConcurrentLinkedQueue messages) {
this.messages = messages;
}
@Override
public void run() {
while(true) {
// this is a 2 step process, probably should synchronize?? i.e. copy and re-initializing
ConcurrentLinkedQueue copy = messages;
messages = new ConcurrentLinkedQueue();
// save to disk using the copy queue
// sleep for x seconds
}
}
}
我想做的想法是:
我的消息被保存到队列中,每隔 x 秒,一个后台线程会创建队列的副本,重新设置原始消息队列,以便它可以开始获取新数据,而旧副本被持久保存到文件/数据库。
这样,任何未来的写入都将写入新队列。
在我的测试中,这不起作用,因为我似乎无法重新初始化传递给线程的队列。
我相信这是因为消息队列是通过引用传入的,但它传递的是引用的副本,并且不允许您更改引用。您可以更改被引用的对象,但不能更改引用。
如果这是真的,那么我有什么选择呢? 我可以在课堂上公开一些可以为我做这件事的方法吗?
注意:当我的应用程序运行时,Chat 对象只创建一次。
Chat 对象将被多个线程访问。
更新
只有一个线程会执行此“持久性”,我希望它在 Chat.messages 队列上工作。我想要它做的只是制作一个集合的副本,然后重新设置聊天的集合,然后它可以花时间将复制的队列版本保存到磁盘。