我对Tomcat不是很熟悉,在我看来它基本上被抽象为cgi服务器,可以在调用之间保存JVM - 我知道它可以做更多的事情.
我正在寻找一种在Tomcat服务器启动时启动后台线程的方法,它会定期更新服务器上下文(在我的特定情况下,这是一个从其他服务中侦听心跳并更新可用性信息的线程,但可以想象各种用途).
有没有标准的方法来做到这一点?上下文的启动和更新/查询?
任何指向相关文档和/或代码示例的指针都将非常感激.
可能重复一次!我使用Tomcat作为我的服务器,并想知道什么是在确定性结果的servlet中生成线程的最佳方法.我正在从servlet操作运行一些长时间运行的更新,并希望完成请求并在后台进行更新.而不是添加像RabbitMQ这样的消息中间件,我想我可以生成一个可以在后台运行并在自己的时间内完成的线程.我在其他SO线程中读到服务器终止服务器生成的线程,以便它能够很好地管理资源.
在使用Tomcat时是否有推荐的方法来生成线程,后台作业.我还使用Spring MVC作为应用程序.
有谁可以在这里提出建议?我有一种情况,用户将通过Java JSP和servlet以交互方式将数据挖掘请求提交给我的应用程序,该应用程序将动态地计算出关于数据的关联规则等.
因为这样的工作可能需要一段时间,我想在服务器上运行某种过程以在后台运行这样的请求,所以它不会"锁定"会话并可能使用大量的服务器内存而造成损害系统的.
由于系统由在MySQL数据库上运行在Tomcat容器中的一系列Java JSP和servlet组成,任何人都可以建议前进的方向吗?
谢谢
摩根先生
我需要获得一些配置并连接到某处的外部资源/对象/系统并将其存储在应用程序范围内.
我可以看到两种设置应用程序的方法:
init()现有的servlet和所需的代码,并将所有构造的对象保留在同一个servlet中.init()来完成工作.然后存储创建的对象ServletContext以与其他servlet共享.以上哪种方法更好?有没有更好的方法在servlet之间共享对象?直接从彼此调用它们......?
我想知道是否可以Timer在应用程序范围内使用bean.
例如,假设我想创建一个计时器任务,每天一次向每个注册会员发送一堆电子邮件.我试图尽可能多地使用JSF,我想知道这是否可以接受(我知道它有点奇怪).
到目前为止,我已经使用了上述所有内容了ServletContextListener.(我不想使用任何应用程序服务器或cron作业,我想在Web应用程序中保留上述内容.)
是否有一种聪明的JSF方式,或者我应该坚持使用旧模式?
我有以下servlet:
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 16252534;
private static int ping = 3000;
private Thread t;
private static boolean shouldStop = false;
@Override
public void init() throws ServletException {
super.init();
t = new Thread(new Runnable() {
@Override
public void run() {
while(!shouldStop) {
System.out.println("Now:" + System.currentTimeMillis());
try {
Thread.sleep(ping);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doGet(req, …Run Code Online (Sandbox Code Playgroud) 我有一个部署到Tomcat服务器的WAR文件,其中一个类将在启动时调用,然后init()方法将安排一个计时器每5小时触发一次以执行某些任务.
我的init()代码如下所示:
public void init()
{
TimerTask parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
Timer parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序运行没有问题,但当我使用/etc/init.d/tomcat7停止关闭Tomcat时,我检查日志(catalina.out)它有一个这样的条目:
严重:Web应用程序[/ MyApplication]似乎已经启动了一个名为[Timer-0]的线程,但未能阻止它.这很可能造成内存泄漏.
我明白这是由我安排计时器引起的,但我的问题是:
setDeamon为true,所以定时器不应该阻止Tomcat关闭,而不是继续运行?谢谢!
UPDATE
我根据一些搜索和DaveHowes的答案将我的代码更改为以下内容.
Timer parserTimer;
TimerTask parserTimerTask;
public void init()
{
parserTimerTask = new TimerTask() {
@Override
public void run() {
XmlParser.parsePage();
}
};
parserTimer = new Timer();
parserTimer.scheduleAtFixedRate(parserTimerTask, 0, PERIOD);
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
Logger logger …Run Code Online (Sandbox Code Playgroud) 我希望每隔6小时从订阅中检索并将订阅源存储到DB.我想在后台有一个计时器线程来完成这个任务.
什么是最好的方式?普通的计时器线程或Quartz API?
我使用servlet和JSP开发了一个Web应用程序.我本身并没有使用任何框架,而是使用我自己的自制MVC框架.我使用MySQL作为后端.
我想做以下事情:
问题是:目前我的所有代码都是从客户端收到的请求运行的.
如何在服务器端运行定期任务?
我现在的一个解决方案是在控制器的init函数中创建一个线程.还有其他选择吗?
有人告诉我,你不应该从在Tomcat下运行的webapp(或任何其他容器,大概是)开始你自己的线程
Runnable myRunnable = new Runnable() {
public void run() {
System.out.println("I'm running");
}
}
new Thread(myRunnable).start();
Run Code Online (Sandbox Code Playgroud)
或类似地:
ScheduledThreadPoolExecutor retrySchedulerService = new ScheduledThreadPoolExecutor(3);
retrySchedulerService.schedule(dlrRetryTask, 120, TimeUnit.SECONDS);
Run Code Online (Sandbox Code Playgroud)
您应该从Tomcat知道的某些线程池中请求一个线程,而不是上述任何一个.这有什么道理,还是完全爆发?