Java 为后台任务servlet创建线程

Java 为后台任务servlet创建线程,java,multithreading,servlets,Java,Multithreading,Servlets,我的问题是: 在我的servlet中,我从一些不相关的地方获取了大量数据。我必须迭代所有这些数据并将其放入数组中,将其转换为JSON对象并将其发送到客户端进行查看。如果在单个响应中执行此操作,则显示结果需要很长时间。因此,我需要进行多线程处理 创建的线程需要继续向列表中添加数据,而主线程在收到数据请求时会定期发送当前可用列表 例如,在第一次请求时,发送的响应是:1 2 3 第二个要求:4、5、6等等 现在我来谈谈实际问题:我不知道如何在servlet中执行多线程。我已经浏览了大量的资源和示例,但

我的问题是: 在我的servlet中,我从一些不相关的地方获取了大量数据。我必须迭代所有这些数据并将其放入数组中,将其转换为JSON对象并将其发送到客户端进行查看。如果在单个响应中执行此操作,则显示结果需要很长时间。因此,我需要进行多线程处理

创建的线程需要继续向列表中添加数据,而主线程在收到数据请求时会定期发送当前可用列表

例如,在第一次请求时,发送的响应是:1 2 3 第二个要求:4、5、6等等

现在我来谈谈实际问题:我不知道如何在servlet中执行多线程。我已经浏览了大量的资源和示例,但这只会让我更加困惑。有些示例在doGet中创建了线程,我认为这是非常错误的,有些示例在init方法中创建了线程,但我不知道如何传递参数并从线程获得结果,如果在init方法中声明它不能是全局变量。还有一些servletContextListener的例子,但我没有发现任何有用或有意义的东西

谁能给我一个可靠的源代码,或者给我一些伪代码来解决我的问题。如果答案与前面提到的情景联系在一起,那将非常有帮助

谢谢

创建的线程需要继续向列表中添加数据,而 主线程在收到数据请求时保持打开状态 定期发送当前可用列表

如果我没弄错的话,你想得到一些数据作为后台服务,并在客户请求时为他们做好准备听起来像是在收集数据

嗯,在web应用程序中创建线程,或者通常是托管环境附带的东西是不同的,隐式创建线程会导致内存泄漏

一个好的解决方案是通过容器上下文/ndi或手动创建线程池。 它必须以可管理的方式创建,您可以通过与环境相关的事件来控制它

ContextListener是您的朋友,有一个context listener类,如下所示

public class dear_daemon implements ServletContextListener,Runnable{
ExecutorService the_pool;
Thread the_evil;
/*following get invoked once the context is called*/
public void contextInitialized(ServletContextEvent sce){
/*initialize the thread-pool, and run evil thread*/}
/*following get invoked once the context is destroying*/
public void contextDestroyed(ServletContextEvent sce){eviling=false;
/*stop evil(this) thread(first), then destroy thread pool*/
}
volatile boolean eviling=true;
public void run(){
 while(eviling){
  /*run Runnable instance which do data fetching using thread-pool*/
 }
}
}
并在web.xml中注册侦听器

拥有一个classrunnable,它执行数据获取,并通过邪恶线程调用它,每个实例使用一个线程

ContextListener可以帮助您通过容器正确地关闭和管理init和hult事件,使用与servlet init相同的方法是可能的,但是请确保使用servlet的destroy方法对hult执行相同的操作

如果您喜欢对它执行线程操作,请确保您执行的操作是线程安全的,因为您有一件事要将数据存储到列表中

如果需要进行任何同步(例如,对提取的数据进行排序),请确保操作正确,否则将面临死锁或低性能代码

如果需要任何IO操作来获取数据,请注意java IO是阻塞的,所以请设置读取和连接超时,或者如果可以处理复杂的NIO事务,请切换到NIO


如果应用这些更改使环境变得复杂,并且您喜欢使用其他解决方案,您可以简单地从web配置文件提取数据,并将其作为外部守护程序服务或应用程序运行,其中应用程序将通过调用您的CGI/Servlet将提取的数据传递到服务器上下文。

请详细解释,一旦向servlet发出请求,您应该从servlet向外部数据请求数据吗?或者servlet应该做一些关于获取数据的背景工作,并为客户端做好准备?为了简单起见,数据已经存在了。现在,后台线程需要开始将数据放入列表中,它可以在请求到来之前开始这样做。当一个请求到来时,doGet只是用list的当前状态进行响应。后台线程一直在向列表中添加数据。另一个请求出现并发送新列表,依此类推。如果有帮助,则从以前的请求中检索数据。我将数据存储在servlet上下文中。现在,我想创建的线程正在将数据更改为列表,很抱歉,我仍然感到困惑。据我所知,servletcontextlistener用于在web应用程序启动之前执行代码。如何在doGet中传递数据表?据我所知,这需要事先将数据存储在某个地方。我认为你误解了上述数据的存在。。。在web应用程序启动后,通过ajax请求接收数据。在收到这些数据后,我希望将整个多线程和数据列表转换为occur@FurqanTariq每个请求都有一个servlet的新线程,因此如果您得到100个异步ajax调用,您将得到100个异步servlet调用,每个调用都将由一个线程运行调用。除非 您将默认的上下文多线程设置为single。
<listener>
    <listener-class>dudes.dear_daemon</listener-class>
</listener>