同步日志条目发布到服务器

发布于 2024-11-01 09:56:20 字数 861 浏览 1 评论 0原文

我的项目有一点问题。我正在开发一个 Android 应用程序,并且想将我的日志发布到服务器。几乎一切都工作正常,但我遇到了一些问题。我的类中有一个处理帖子的 ArrayList:

private ArrayList<String> logsToPost = new ArrayList<String>();

以及一个将数据放入此列表的方法和一个每 20 秒运行一次并上传日志并清空列表的单独线程。问题是,如果我在线程尝试上传数据并清理列表时尝试写入此列表,则会收到 ConcurrentModificationException。我的代码如下所示:

Iterator<String> keyIter = logsToPost.iterator();
        while (keyIter.hasNext()) {
        String next = keyIter.next();
        String[] params = next.split(FormFactory.FUNCTION_SEP);
        HttpData hd = HttpRequest.post(LOGCAT_LOG_URL, "userId=" + sb.userId + "&pdaId=" + sb.pdaId
                + "&tag=" + params[0] + "&logContent=" + params[1]);
        logsToPost.remove(next);
        }

我知道有一个同步列表和同步块,但我无法让同步列表在我的机器人上工作。您对如何实现此日志记录程序有任何想法吗?我尝试使用 volatile 关键字,但仍然遇到异常。

I have a little problem with my project. I'm developing an application for Android and a want to post my logs to a server. Almost everything works fine, but I got a little problem. I have an ArrayList in my class which handles the posts:

private ArrayList<String> logsToPost = new ArrayList<String>();

and a method which puts data to this list and a separate thread which runs every 20 seconds and uploads the logs and empties the list after that. The problem is that I get a ConcurrentModificationException if I'm trying to write to this list while the thread tries to upload the data and clean the list. My code looks like this:

Iterator<String> keyIter = logsToPost.iterator();
        while (keyIter.hasNext()) {
        String next = keyIter.next();
        String[] params = next.split(FormFactory.FUNCTION_SEP);
        HttpData hd = HttpRequest.post(LOGCAT_LOG_URL, "userId=" + sb.userId + "&pdaId=" + sb.pdaId
                + "&tag=" + params[0] + "&logContent=" + params[1]);
        logsToPost.remove(next);
        }

I know that there is a synchronizedList, and synchronized blocks but I can't get synchronizedList to work on my droid. Do you have any ideas how can I implement this logging procedure? I tried using the volatile keyword but I still get the exception.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

何时共饮酒 2024-11-08 09:56:20

从 Java 角度来看:

您的代码应该始终导致异常,因为您使用 ArrayList.remove 而不是 Iterator.remove 修改 ArrayList,同时还对其进行迭代。

进行此更改应该可以在大多数情况下解决您的问题:

Iterator<String> keyIter = logsToPost.iterator();
while (keyIter.hasNext()) {
    String next = keyIter.next();
    //do something
    keyIter.remove();
}

为了进一步强化您的任务,避免失败的风险,您应该考虑在日志记录任务开始时自动交换 ArrayList 的实例。所以工作流程是:

ArrayList<String> logsToPost = logListReference.getAndSet(new ArrayList<String>());
for (String logEntry:logsToPost) {
    //doSomething
}

From a Java perspective:

Your code should always result in an exception since you are modifying the ArrayList using the ArrayList.remove instead of Iterator.remove while also iterating over it.

Making this change should fix your problem most of the time:

Iterator<String> keyIter = logsToPost.iterator();
while (keyIter.hasNext()) {
    String next = keyIter.next();
    //do something
    keyIter.remove();
}

To further harden your task from the risk of failure, you should consider atomically swapping the instance of the ArrayList at the start of your logging task. So the work flow would be:

ArrayList<String> logsToPost = logListReference.getAndSet(new ArrayList<String>());
for (String logEntry:logsToPost) {
    //doSomething
}
雪若未夕 2024-11-08 09:56:20

在发送过程开始时交换列表是否是一个解决方案?这样发送进程始终使用“旧”列表,而写入进程始终使用“新”列表。

那么你只需要同步写入新列表,并交换它们,

我来说明一下:

public class ListHolder {

  private List newList = new List();

  public syncronized List exchangeAndGetOld() {
    List oldList = this.newList;
    this.newList = new List();
    return oldList();
  }

  public syncronized addToNewList(Object item) {
    newList.add(item);
  }
}

Would it be a solution to have exchange the lists when the sending process starts. So that the sending process always use the "old" list, and the writing process the "new" list.

Then you need only to synchronize writing to the new list, and exchanging them,

Let me illustrate it:

public class ListHolder {

  private List newList = new List();

  public syncronized List exchangeAndGetOld() {
    List oldList = this.newList;
    this.newList = new List();
    return oldList();
  }

  public syncronized addToNewList(Object item) {
    newList.add(item);
  }
}
☆獨立☆ 2024-11-08 09:56:20
  1. 对共享列表使用同步集合:

    private Vector messagesToPost = new Vector();

  2. 在上传数据之前获取该集合的副本:

ArrayList;日志上传;
同步(logsToPost){
  logsToUpload = new ArrayList(logsToPost);
  LogsToPost.clear();
}
  1. 在发送循环中使用集合的副本:

    Iterator keyIter = messagesToUpload.iterator();

  1. Use synchronized collection for the shared list:

    private Vector logsToPost = new Vector();

  2. Get the copy of that collection before you upload data:

ArrayList<String> logsToUpload;
synchronized(logsToPost) {
  logsToUpload = new ArrayList<String>(logsToPost);
  logsToPost.clear();
}
  1. Use the copy of the collection in your sending loop:

    Iterator keyIter = logsToUpload.iterator();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文