我有一个webapp,每个请求都会在某些集合中存储一些信息(例如客户端IP地址)。我不时需要清空它,将所有元素序列化为xml并将xml发送到其他Web服务。我可以为每个请求创建并发送一个xml,但我宁愿以块的形式发送数据(不要经常与webservice通信)。我没有关于集合的最大大小的要求(除了没有outofmemoryerror),必须发送文件的时间段和最小/最大文件大小。有时jvm崩溃并且我们丢失了存储在内存中的所有数据也是可以接受的。
据我所知,许多线程(servlet容器生成的线程)将向集合添加元素,偶尔一个消费者线程将从集合中获取所有元素,将它们序列化为xml并发送文件。你能推荐一下这个设计吗?
我应该在消费者线程中使用忙等待吗? 哪个线程(生产者或消费者)应检查集合大小是否为某个最大/阈值大小? 我可以在集合上使用synchronize并在生产者端使用notifyAll来通知消费者吗? 我应该在消费者端使用synchronize和while(size< MAX){wait()}吗? 排水要比List temp = new ArrayList<>(collection)更好; ?
这是我的第一个念头。我确信有很多理由批评它:
public void add(Info info){
synchronized (collection) {
collection.add(info);
if (collection.size() > THRESHOLD) {
collection.notify();
}
}
}
public void send(){
while (true) {
List<Info> temp = null;
synchronized (collection) {
try {
collection.wait();
} catch (InterruptedException e) {
}
List<Info> temp = new ArrayList<>(collection);
collection.clear();
}
serializeAndSend(temp);
}
}
答案 0 :(得分:2)
至少考虑使用LinkedBlockingQueue
或java.util.concurrent
中的其他内容,而不是自己动手。
按原样,您当前的代码无法使用,因为notify()
和wait()
调用无法针对同一对象进行操作。
您的要求很有趣。例如,如果JVM死亡(出于任何原因),并且您丢失了所有排队的数据,该怎么办?无论如何,按照您的评论 - 您仍然可以执行类似于之前的操作 - 通过自定义方法过滤所有添加操作,如果集合达到特定大小,则serializeAndSend
。但是,如果您遵循这种方法,那么您真的不需要具有并发支持的集合。我还看到您更新了代码以致电collection.wait()
,这很好。