【问题标题】:Spring long polling ConcurrentModificationExceptionSpring长轮询ConcurrentModificationException
【发布时间】:2017-07-29 13:17:18
【问题描述】:

基本上我有一个简单的新闻应用程序,现在我想在有人添加或删除新闻时为所有用户自动更新新闻列表,它有点工作但有时我得到 ConcurrentModificationException,我只需要帮助来编写这个方法:

@GetMapping("/pollnews")
@ResponseBody
public DeferredResult<ModelAndView> poll(Model model){
    DeferredResult<ModelAndView> result = new DeferredResult<>();
    new Thread(new Runnable() {

        @Override
        public void run() {
            while(true){
                if(changeOccured){
                    changeOccured = false;
                    model.addAttribute("news", newsService.getAllNews());
                    result.setResult(new ModelAndView("partial"));
                    break;
                }
            }
        }
    }).start();
    return result;
}

堆栈跟踪:

Exception in thread "Thread-13" java.util.ConcurrentModificationException
at java.util.ArrayList.sort(ArrayList.java:1456)
at com.newsapp.SpringNews.Service.NewsService.getAllNews(NewsService.java:25)
at com.newsapp.SpringNews.Controller.ViewController$1.run(ViewController.java:125)
at java.lang.Thread.run(Thread.java:748)

【问题讨论】:

  • 您指定异常发生在哪一行?
  • 发生在newsService类和getAllnews()方法中,不过没关系,因为我觉得我这个poll()方法写错了,问题可能就在那里……
  • 您可以将堆栈跟踪添加到您的问题中吗?因为我看不出你的方法有什么问题
  • 您的异常在 NewsService.getAllNews(NewsService.java:25) 中,但是您正在显示方法 poll()。我们需要getAllNews()
  • 其他问题与问题无关,但已发布代码。每次调用 /pollnews 时,您的 poll() 方法都会生成一个新线程,并且 while(true) 将永远不会退出。这会导致一段时间内存不足。

标签: java ajax spring concurrency long-polling


【解决方案1】:

您使用数组列表同时写入数据和获取数据。 ArrayList 将失败。您需要一个管理并发访问的 List 实现:

无论如何,这样拉是非常危险的 - 你会遇到网络超时,你也会杀死你的服务器,在 while true 上会有很多线程循环(在你的代码上没有等待!)。

更好的方法是使用 ServerSideEvent (SSE) 和事件系统。

这里有一篇关于使用 spring https://golb.hplar.ch/p/Server-Sent-Events-with-Spring 的帖子

它管理一个事件系统,使监听器和生产者完全分离。

【讨论】:

  • 感谢您的建议,但我想让它尽可能简单,您是否认为可以对其进行重构以使其更好和工作?
  • 编辑添加并发问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-08
  • 2011-04-20
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
相关资源
最近更新 更多